firebase-tools 13.11.3 → 13.11.4
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/commands/index.js +9 -11
- package/lib/commands/init.js +5 -7
- package/lib/crashlytics/buildToolsJarHelper.js +1 -1
- package/lib/dataconnect/client.js +1 -1
- package/lib/emulator/controller.js +0 -3
- package/lib/emulator/dataconnectEmulator.js +107 -12
- package/lib/emulator/hub.js +1 -1
- package/lib/emulator/portUtils.js +9 -0
- package/lib/experiments.js +2 -2
- package/package.json +1 -1
package/lib/commands/index.js
CHANGED
|
@@ -200,17 +200,15 @@ function load(client) {
|
|
|
200
200
|
client.setup.emulators.pubsub = loadCommand("setup-emulators-pubsub");
|
|
201
201
|
client.setup.emulators.storage = loadCommand("setup-emulators-storage");
|
|
202
202
|
client.setup.emulators.ui = loadCommand("setup-emulators-ui");
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
client.dataconnect.sdk.generate = loadCommand("dataconnect-sdk-generate");
|
|
213
|
-
}
|
|
203
|
+
client.dataconnect = {};
|
|
204
|
+
client.setup.emulators.dataconnect = loadCommand("setup-emulators-dataconnect");
|
|
205
|
+
client.dataconnect.services = {};
|
|
206
|
+
client.dataconnect.services.list = loadCommand("dataconnect-services-list");
|
|
207
|
+
client.dataconnect.sql = {};
|
|
208
|
+
client.dataconnect.sql.diff = loadCommand("dataconnect-sql-diff");
|
|
209
|
+
client.dataconnect.sql.migrate = loadCommand("dataconnect-sql-migrate");
|
|
210
|
+
client.dataconnect.sdk = {};
|
|
211
|
+
client.dataconnect.sdk.generate = loadCommand("dataconnect-sdk-generate");
|
|
214
212
|
client.target = loadCommand("target");
|
|
215
213
|
client.target.apply = loadCommand("target-apply");
|
|
216
214
|
client.target.clear = loadCommand("target-clear");
|
package/lib/commands/init.js
CHANGED
|
@@ -76,13 +76,11 @@ if ((0, experiments_1.isEnabled)("genkit")) {
|
|
|
76
76
|
checked: false,
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
85
|
-
}
|
|
79
|
+
choices.push({
|
|
80
|
+
value: "dataconnect",
|
|
81
|
+
name: "Data Connect: Set up a Firebase Data Connect service.",
|
|
82
|
+
checked: false,
|
|
83
|
+
});
|
|
86
84
|
const featureNames = choices.map((choice) => choice.value);
|
|
87
85
|
const DESCRIPTION = `Interactively configure the current directory as a Firebase project or initialize new features in an already configured Firebase project directory.
|
|
88
86
|
|
|
@@ -12,7 +12,7 @@ const rimraf = require("rimraf");
|
|
|
12
12
|
const utils = require("../utils");
|
|
13
13
|
const JAR_CACHE_DIR = process.env.FIREBASE_CRASHLYTICS_BUILDTOOLS_PATH ||
|
|
14
14
|
path.join(os.homedir(), ".cache", "firebase", "crashlytics", "buildtools");
|
|
15
|
-
const JAR_VERSION = "3.0.
|
|
15
|
+
const JAR_VERSION = "3.0.2";
|
|
16
16
|
const JAR_URL = `https://dl.google.com/android/maven2/com/google/firebase/firebase-crashlytics-buildtools/${JAR_VERSION}/firebase-crashlytics-buildtools-${JAR_VERSION}.jar`;
|
|
17
17
|
async function fetchBuildtoolsJar() {
|
|
18
18
|
if (process.env.CRASHLYTICS_LOCAL_JAR) {
|
|
@@ -132,7 +132,7 @@ async function listConnectors(serviceName) {
|
|
|
132
132
|
pageToken,
|
|
133
133
|
},
|
|
134
134
|
});
|
|
135
|
-
connectors.push(...res.body.connectors);
|
|
135
|
+
connectors.push(...(res.body.connectors || []));
|
|
136
136
|
if (res.body.nextPageToken) {
|
|
137
137
|
await getNextPage(res.body.nextPageToken);
|
|
138
138
|
}
|
|
@@ -539,9 +539,6 @@ async function startAll(options, showUI = true, runningTestScript = false) {
|
|
|
539
539
|
rc: options.rc,
|
|
540
540
|
});
|
|
541
541
|
await startEmulator(dataConnectEmulator);
|
|
542
|
-
if (!utils.isVSCodeExtension()) {
|
|
543
|
-
await dataConnectEmulator.connectToPostgres();
|
|
544
|
-
}
|
|
545
542
|
}
|
|
546
543
|
if (listenForEmulator.storage) {
|
|
547
544
|
const storageAddr = legacyGetFirstAddr(types_1.Emulators.STORAGE);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataConnectEmulatorClient = exports.DataConnectEmulator = void 0;
|
|
3
|
+
exports.checkIfDataConnectEmulatorRunningOnAddress = exports.DataConnectEmulatorClient = exports.DataConnectEmulator = exports.dataConnectEmulatorEvents = void 0;
|
|
4
4
|
const childProcess = require("child_process");
|
|
5
5
|
const clc = require("colorette");
|
|
6
6
|
const api_1 = require("../api");
|
|
@@ -11,10 +11,16 @@ const error_1 = require("../error");
|
|
|
11
11
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
12
12
|
const types_2 = require("../dataconnect/types");
|
|
13
13
|
const portUtils_1 = require("./portUtils");
|
|
14
|
+
const apiv2_1 = require("../apiv2");
|
|
14
15
|
const registry_1 = require("./registry");
|
|
16
|
+
const load_1 = require("../dataconnect/load");
|
|
17
|
+
const utils_1 = require("../utils");
|
|
18
|
+
const events_1 = require("events");
|
|
19
|
+
exports.dataConnectEmulatorEvents = new events_1.EventEmitter();
|
|
15
20
|
class DataConnectEmulator {
|
|
16
21
|
constructor(args) {
|
|
17
22
|
this.args = args;
|
|
23
|
+
this.usingExistingEmulator = false;
|
|
18
24
|
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.DATACONNECT);
|
|
19
25
|
this.emulatorClient = new DataConnectEmulatorClient();
|
|
20
26
|
}
|
|
@@ -33,17 +39,39 @@ class DataConnectEmulator {
|
|
|
33
39
|
catch (err) {
|
|
34
40
|
this.logger.log("DEBUG", `'fdc build' failed with error: ${err.message}`);
|
|
35
41
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
+
const alreadyRunning = await this.discoverRunningInstance();
|
|
43
|
+
if (alreadyRunning) {
|
|
44
|
+
this.logger.logLabeled("INFO", "Data Connect", "Detected an instance of the emulator already running with your service, reusing it. This emulator will not be shut down at the end of this command.");
|
|
45
|
+
this.usingExistingEmulator = true;
|
|
46
|
+
this.watchUnmanagedInstance();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
await (0, downloadableEmulators_1.start)(types_1.Emulators.DATACONNECT, {
|
|
50
|
+
auto_download: this.args.auto_download,
|
|
51
|
+
listen: (0, portUtils_1.listenSpecsToString)(this.args.listen),
|
|
52
|
+
config_dir: this.args.configDir,
|
|
53
|
+
service_location: this.args.locationId,
|
|
54
|
+
});
|
|
55
|
+
this.usingExistingEmulator = false;
|
|
56
|
+
}
|
|
57
|
+
if (!(0, utils_1.isVSCodeExtension)()) {
|
|
58
|
+
await this.connectToPostgres();
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
42
61
|
}
|
|
43
|
-
connect() {
|
|
62
|
+
async connect() {
|
|
63
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
64
|
+
if (!emuInfo) {
|
|
65
|
+
this.logger.logLabeled("ERROR", "Data Connect", "Could not connect to Data Connect emulator. Check dataconnect-debug.log for more details.");
|
|
66
|
+
return Promise.reject();
|
|
67
|
+
}
|
|
44
68
|
return Promise.resolve();
|
|
45
69
|
}
|
|
46
|
-
stop() {
|
|
70
|
+
async stop() {
|
|
71
|
+
if (this.usingExistingEmulator) {
|
|
72
|
+
this.logger.logLabeled("INFO", "Data Connect", "Skipping cleanup of Data Connect emulator, as it was not started by this process.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
47
75
|
return (0, downloadableEmulators_1.stop)(types_1.Emulators.DATACONNECT);
|
|
48
76
|
}
|
|
49
77
|
getInfo() {
|
|
@@ -107,6 +135,35 @@ class DataConnectEmulator {
|
|
|
107
135
|
}
|
|
108
136
|
return (_b = (_a = this.args.rc.getDataconnect()) === null || _a === void 0 ? void 0 : _a.postgres) === null || _b === void 0 ? void 0 : _b.localConnectionString;
|
|
109
137
|
}
|
|
138
|
+
async discoverRunningInstance() {
|
|
139
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
140
|
+
if (!emuInfo) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const serviceInfo = await (0, load_1.load)(this.args.projectId, this.args.locationId, this.args.configDir);
|
|
144
|
+
const sameService = emuInfo.services.find((s) => serviceInfo.dataConnectYaml.serviceId === s.serviceId);
|
|
145
|
+
if (!sameService) {
|
|
146
|
+
throw new error_1.FirebaseError(`There is a Data Connect emulator already running on ${this.args.listen[0].address}:${this.args.listen[0].port}, but it is emulating a different service. Please stop that instance of the Data Connect emulator, or specify a different port in 'firebase.json'`);
|
|
147
|
+
}
|
|
148
|
+
if (sameService.connectionString &&
|
|
149
|
+
sameService.connectionString !== this.getLocalConectionString()) {
|
|
150
|
+
throw new error_1.FirebaseError(`There is a Data Connect emulator already running, but it is using a different Postgres connection string. Please stop that instance of the Data Connect emulator, or specify a different port in 'firebase.json'`);
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
watchUnmanagedInstance() {
|
|
155
|
+
return setInterval(async () => {
|
|
156
|
+
if (!this.usingExistingEmulator) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const emuInfo = await this.emulatorClient.getInfo();
|
|
160
|
+
if (!emuInfo) {
|
|
161
|
+
this.logger.logLabeled("INFO", "Data Connect", "The already running emulator seems to have shut down. Starting a new instance of the Data Connect emulator...");
|
|
162
|
+
await this.start();
|
|
163
|
+
exports.dataConnectEmulatorEvents.emit("restart");
|
|
164
|
+
}
|
|
165
|
+
}, 5000);
|
|
166
|
+
}
|
|
110
167
|
async connectToPostgres(localConnectionString, database, serviceId) {
|
|
111
168
|
const connectionString = localConnectionString !== null && localConnectionString !== void 0 ? localConnectionString : this.getLocalConectionString();
|
|
112
169
|
if (!connectionString) {
|
|
@@ -114,8 +171,22 @@ class DataConnectEmulator {
|
|
|
114
171
|
Run ${clc.bold("firebase setup:emulators:dataconnect")} to set up a Postgres connection.`;
|
|
115
172
|
throw new error_1.FirebaseError(msg);
|
|
116
173
|
}
|
|
117
|
-
|
|
118
|
-
|
|
174
|
+
const MAX_RETRIES = 3;
|
|
175
|
+
for (let i = 1; i <= MAX_RETRIES; i++) {
|
|
176
|
+
try {
|
|
177
|
+
this.logger.logLabeled("DEBUG", "Data Connect", `Connecting to ${connectionString}}`);
|
|
178
|
+
await this.emulatorClient.configureEmulator({ connectionString, database, serviceId });
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
if (i === MAX_RETRIES) {
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
this.logger.logLabeled("DEBUG", "Data Connect", `Retrying connectToPostgress call (${i} of ${MAX_RETRIES} attempts): ${err}`);
|
|
186
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
119
190
|
}
|
|
120
191
|
}
|
|
121
192
|
exports.DataConnectEmulator = DataConnectEmulator;
|
|
@@ -124,6 +195,7 @@ class DataConnectEmulatorClient {
|
|
|
124
195
|
this.client = undefined;
|
|
125
196
|
}
|
|
126
197
|
async configureEmulator(body) {
|
|
198
|
+
var _a, _b;
|
|
127
199
|
if (!this.client) {
|
|
128
200
|
this.client = registry_1.EmulatorRegistry.client(types_1.Emulators.DATACONNECT);
|
|
129
201
|
}
|
|
@@ -133,10 +205,33 @@ class DataConnectEmulatorClient {
|
|
|
133
205
|
}
|
|
134
206
|
catch (err) {
|
|
135
207
|
if (err.status === 500) {
|
|
136
|
-
throw new error_1.FirebaseError(`Data Connect emulator: ${err.context.body.message}`);
|
|
208
|
+
throw new error_1.FirebaseError(`Data Connect emulator: ${(_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.message}`);
|
|
137
209
|
}
|
|
138
210
|
throw err;
|
|
139
211
|
}
|
|
140
212
|
}
|
|
213
|
+
async getInfo() {
|
|
214
|
+
if (!this.client) {
|
|
215
|
+
this.client = registry_1.EmulatorRegistry.client(types_1.Emulators.DATACONNECT);
|
|
216
|
+
}
|
|
217
|
+
return getInfo(this.client);
|
|
218
|
+
}
|
|
141
219
|
}
|
|
142
220
|
exports.DataConnectEmulatorClient = DataConnectEmulatorClient;
|
|
221
|
+
async function checkIfDataConnectEmulatorRunningOnAddress(l) {
|
|
222
|
+
const client = new apiv2_1.Client({
|
|
223
|
+
urlPrefix: `http:/${l.family === "IPv6" ? `[${l.address}]` : l.address}:${l.port}`,
|
|
224
|
+
auth: false,
|
|
225
|
+
});
|
|
226
|
+
return getInfo(client);
|
|
227
|
+
}
|
|
228
|
+
exports.checkIfDataConnectEmulatorRunningOnAddress = checkIfDataConnectEmulatorRunningOnAddress;
|
|
229
|
+
async function getInfo(client) {
|
|
230
|
+
try {
|
|
231
|
+
const res = await client.get("emulator/info");
|
|
232
|
+
return res.body;
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
package/lib/emulator/hub.js
CHANGED
|
@@ -149,7 +149,7 @@ class EmulatorHub extends ExpressBasedEmulator_1.ExpressBasedEmulator {
|
|
|
149
149
|
const locatorPath = EmulatorHub.getLocatorFilePath(this.args.projectId);
|
|
150
150
|
return new Promise((resolve, reject) => {
|
|
151
151
|
fs.unlink(locatorPath, (e) => {
|
|
152
|
-
if (e) {
|
|
152
|
+
if (e && e.code !== "ENOENT") {
|
|
153
153
|
reject(e);
|
|
154
154
|
}
|
|
155
155
|
else {
|
|
@@ -11,6 +11,7 @@ const types_1 = require("./types");
|
|
|
11
11
|
const constants_1 = require("./constants");
|
|
12
12
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
13
13
|
const node_child_process_1 = require("node:child_process");
|
|
14
|
+
const dataconnectEmulator_1 = require("./dataconnectEmulator");
|
|
14
15
|
const RESTRICTED_PORTS = new Set([
|
|
15
16
|
1,
|
|
16
17
|
7,
|
|
@@ -219,6 +220,14 @@ async function resolveHostAndAssignPorts(listenConfig) {
|
|
|
219
220
|
available.push(listen);
|
|
220
221
|
}
|
|
221
222
|
else {
|
|
223
|
+
if (/^dataconnect/i.exec(name)) {
|
|
224
|
+
const alreadyRunning = await (0, dataconnectEmulator_1.checkIfDataConnectEmulatorRunningOnAddress)(listen);
|
|
225
|
+
if (alreadyRunning) {
|
|
226
|
+
emuLogger.logLabeled("DEBUG", "dataconnect", `Detected already running emulator on ${listen.address}:${listen.port}. Will attempt to reuse it.`);
|
|
227
|
+
}
|
|
228
|
+
available.push(listen);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
222
231
|
if (!portFixed) {
|
|
223
232
|
if (i > 0) {
|
|
224
233
|
emuLogger.logLabeled("DEBUG", name, `Port ${p} taken on secondary address ${addr.address}, will keep searching to find a better port.`);
|
package/lib/experiments.js
CHANGED
|
@@ -92,8 +92,8 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
92
92
|
public: false,
|
|
93
93
|
},
|
|
94
94
|
dataconnect: {
|
|
95
|
-
shortDescription: "
|
|
96
|
-
fullDescription: "
|
|
95
|
+
shortDescription: "Deprecated. Previosuly, enabled Data Connect related features.",
|
|
96
|
+
fullDescription: "Deprecated. Previously, enabled Data Connect related features.",
|
|
97
97
|
public: false,
|
|
98
98
|
},
|
|
99
99
|
genkit: {
|