firebase-tools 13.9.0 → 13.10.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/dataconnect/client.js +1 -1
- package/lib/dataconnect/errors.js +21 -13
- package/lib/dataconnect/provisionCloudSql.js +24 -13
- package/lib/dataconnect/schemaMigration.js +82 -43
- package/lib/deploy/functions/runtimes/discovery/index.js +2 -1
- package/lib/emulator/downloadableEmulators.js +3 -3
- package/lib/frameworks/next/utils.js +0 -1
- package/lib/gcp/cloudsql/cloudsqladmin.js +2 -0
- package/lib/gcp/cloudsql/connect.js +9 -6
- package/lib/requireAuth.js +3 -0
- package/package.json +2 -2
|
@@ -56,7 +56,7 @@ async function createService(projectId, locationId, serviceId) {
|
|
|
56
56
|
}
|
|
57
57
|
exports.createService = createService;
|
|
58
58
|
async function deleteService(projectId, locationId, serviceId) {
|
|
59
|
-
const op = await dataconnectClient().delete(`projects/${projectId}/locations/${locationId}/services/${serviceId}
|
|
59
|
+
const op = await dataconnectClient().delete(`projects/${projectId}/locations/${locationId}/services/${serviceId}`);
|
|
60
60
|
const pollRes = await operationPoller.pollOperation({
|
|
61
61
|
apiOrigin: (0, api_1.dataconnectOrigin)(),
|
|
62
62
|
apiVersion: DATACONNECT_API_VERSION,
|
|
@@ -5,27 +5,35 @@ const INCOMPATIBLE_SCHEMA_ERROR_TYPESTRING = "IncompatibleSqlSchemaError";
|
|
|
5
5
|
const PRECONDITION_ERROR_TYPESTRING = "type.googleapis.com/google.rpc.PreconditionFailure";
|
|
6
6
|
const INCOMPATIBLE_CONNECTOR_TYPE = "INCOMPATIBLE_CONNECTOR";
|
|
7
7
|
function getIncompatibleSchemaError(err) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
throw err;
|
|
8
|
+
const incompatibles = errorDetails(err, INCOMPATIBLE_SCHEMA_ERROR_TYPESTRING);
|
|
9
|
+
if (incompatibles.length === 0) {
|
|
10
|
+
return undefined;
|
|
12
11
|
}
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
12
|
+
const incompatible = incompatibles[0];
|
|
13
|
+
const preconditionErrs = errorDetails(err, PRECONDITION_ERROR_TYPESTRING);
|
|
14
|
+
const violationTypes = (incompatible.violationType = preconditionErrs
|
|
15
|
+
.flatMap((preCondErr) => preCondErr.violations)
|
|
16
|
+
.flatMap((viol) => viol.type)
|
|
17
|
+
.filter((type) => type === "INACCESSIBLE_SCHEMA" || type === "INCOMPATIBLE_SCHEMA"));
|
|
18
|
+
incompatible.violationType = violationTypes[0];
|
|
19
|
+
return incompatible;
|
|
16
20
|
}
|
|
17
21
|
exports.getIncompatibleSchemaError = getIncompatibleSchemaError;
|
|
18
22
|
function getInvalidConnectors(err) {
|
|
19
|
-
var _a, _b
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const preconditionErrs = errorDetails(err, PRECONDITION_ERROR_TYPESTRING);
|
|
20
25
|
const invalidConns = [];
|
|
21
|
-
const original = ((_b = (_a = err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) || (err === null || err === void 0 ? void 0 : err.orignal);
|
|
22
|
-
const details = original === null || original === void 0 ? void 0 : original.details;
|
|
23
|
-
const preconditionErrs = details === null || details === void 0 ? void 0 : details.filter((d) => { var _a; return (_a = d["@type"]) === null || _a === void 0 ? void 0 : _a.includes(PRECONDITION_ERROR_TYPESTRING); });
|
|
24
26
|
for (const preconditionErr of preconditionErrs) {
|
|
25
|
-
const incompatibleConnViolation = (
|
|
26
|
-
const newConns = (
|
|
27
|
+
const incompatibleConnViolation = (_a = preconditionErr === null || preconditionErr === void 0 ? void 0 : preconditionErr.violations) === null || _a === void 0 ? void 0 : _a.filter((v) => v.type === INCOMPATIBLE_CONNECTOR_TYPE);
|
|
28
|
+
const newConns = (_b = incompatibleConnViolation === null || incompatibleConnViolation === void 0 ? void 0 : incompatibleConnViolation.map((i) => i.subject)) !== null && _b !== void 0 ? _b : [];
|
|
27
29
|
invalidConns.push(...newConns);
|
|
28
30
|
}
|
|
29
31
|
return invalidConns;
|
|
30
32
|
}
|
|
31
33
|
exports.getInvalidConnectors = getInvalidConnectors;
|
|
34
|
+
function errorDetails(err, ofType) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
const original = ((_b = (_a = err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) || (err === null || err === void 0 ? void 0 : err.original);
|
|
37
|
+
const details = original === null || original === void 0 ? void 0 : original.details;
|
|
38
|
+
return (details === null || details === void 0 ? void 0 : details.filter((d) => { var _a; return (_a = d["@type"]) === null || _a === void 0 ? void 0 : _a.includes(ofType); })) || [];
|
|
39
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getUpdateReason = exports.provisionCloudSql = void 0;
|
|
4
4
|
const cloudSqlAdminClient = require("../gcp/cloudsql/cloudsqladmin");
|
|
5
5
|
const utils = require("../utils");
|
|
6
6
|
const checkIam_1 = require("./checkIam");
|
|
@@ -15,10 +15,12 @@ async function provisionCloudSql(args) {
|
|
|
15
15
|
const existingInstance = await cloudSqlAdminClient.getInstance(projectId, instanceId);
|
|
16
16
|
silent || utils.logLabeledBullet("dataconnect", `Found existing instance ${instanceId}.`);
|
|
17
17
|
connectionName = (existingInstance === null || existingInstance === void 0 ? void 0 : existingInstance.connectionName) || "";
|
|
18
|
-
|
|
18
|
+
const why = getUpdateReason(existingInstance, enableGoogleMlIntegration);
|
|
19
|
+
if (why) {
|
|
19
20
|
silent ||
|
|
20
21
|
utils.logLabeledBullet("dataconnect", `Instance ${instanceId} settings not compatible with Firebase Data Connect. ` +
|
|
21
|
-
`Updating instance
|
|
22
|
+
`Updating instance. This may take a few minutes...` +
|
|
23
|
+
why);
|
|
22
24
|
await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.updateInstanceForDataConnect(existingInstance, enableGoogleMlIntegration), "Updating your instance...");
|
|
23
25
|
silent || utils.logLabeledBullet("dataconnect", "Instance updated");
|
|
24
26
|
}
|
|
@@ -44,10 +46,15 @@ async function provisionCloudSql(args) {
|
|
|
44
46
|
silent || utils.logLabeledBullet("dataconnect", `Found existing database ${databaseId}.`);
|
|
45
47
|
}
|
|
46
48
|
catch (err) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
if (err.status === 404) {
|
|
50
|
+
silent ||
|
|
51
|
+
utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found, creating it now...`);
|
|
52
|
+
await cloudSqlAdminClient.createDatabase(projectId, instanceId, databaseId);
|
|
53
|
+
silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} created.`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
silent || utils.logLabeledWarning("dataconnect", `Database ${databaseId} is not accessible.`);
|
|
57
|
+
}
|
|
51
58
|
}
|
|
52
59
|
if (enableGoogleMlIntegration) {
|
|
53
60
|
await (0, checkIam_1.grantRolesToCloudSqlServiceAccount)(projectId, instanceId, [GOOGLE_ML_INTEGRATION_ROLE]);
|
|
@@ -55,21 +62,25 @@ async function provisionCloudSql(args) {
|
|
|
55
62
|
return connectionName;
|
|
56
63
|
}
|
|
57
64
|
exports.provisionCloudSql = provisionCloudSql;
|
|
58
|
-
function
|
|
65
|
+
function getUpdateReason(instance, requireGoogleMlIntegration) {
|
|
59
66
|
var _a, _b, _c, _d;
|
|
67
|
+
let reason = "";
|
|
60
68
|
const settings = instance.settings;
|
|
61
69
|
if (!((_a = settings.ipConfiguration) === null || _a === void 0 ? void 0 : _a.ipv4Enabled)) {
|
|
62
|
-
|
|
70
|
+
reason += "\n - to enable public IP.";
|
|
63
71
|
}
|
|
64
72
|
if (requireGoogleMlIntegration) {
|
|
65
73
|
if (!settings.enableGoogleMlIntegration) {
|
|
66
|
-
|
|
74
|
+
reason += "\n - to enable Google ML integration.";
|
|
67
75
|
}
|
|
68
76
|
if (!((_b = settings.databaseFlags) === null || _b === void 0 ? void 0 : _b.some((f) => f.name === "cloudsql.enable_google_ml_integration" && f.value === "on"))) {
|
|
69
|
-
|
|
77
|
+
reason += "\n - to enable Google ML integration database flag.";
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
const isIamEnabled = (_d = (_c = settings.databaseFlags) === null || _c === void 0 ? void 0 : _c.some((f) => f.name === "cloudsql.iam_authentication" && f.value === "on")) !== null && _d !== void 0 ? _d : false;
|
|
73
|
-
|
|
81
|
+
if (!isIamEnabled) {
|
|
82
|
+
reason += "\n - to enable IAM authentication database flag.";
|
|
83
|
+
}
|
|
84
|
+
return reason;
|
|
74
85
|
}
|
|
75
|
-
exports.
|
|
86
|
+
exports.getUpdateReason = getUpdateReason;
|
|
@@ -14,44 +14,49 @@ const utils_1 = require("../utils");
|
|
|
14
14
|
const errors = require("./errors");
|
|
15
15
|
async function diffSchema(schema) {
|
|
16
16
|
const { serviceName, instanceName, databaseId } = getIdentifiers(schema);
|
|
17
|
-
await ensureServiceIsConnectedToCloudSql(serviceName, instanceName, databaseId);
|
|
17
|
+
await ensureServiceIsConnectedToCloudSql(serviceName, instanceName, databaseId, false);
|
|
18
18
|
try {
|
|
19
19
|
await (0, client_1.upsertSchema)(schema, true);
|
|
20
|
+
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema is up to date.`);
|
|
20
21
|
}
|
|
21
22
|
catch (err) {
|
|
23
|
+
if (err.status !== 400) {
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
22
26
|
const invalidConnectors = errors.getInvalidConnectors(err);
|
|
27
|
+
const incompatible = errors.getIncompatibleSchemaError(err);
|
|
28
|
+
if (!incompatible && !invalidConnectors.length) {
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
23
31
|
if (invalidConnectors.length) {
|
|
24
32
|
displayInvalidConnectors(invalidConnectors);
|
|
25
33
|
}
|
|
26
|
-
const incompatible = errors.getIncompatibleSchemaError(err);
|
|
27
34
|
if (incompatible) {
|
|
28
35
|
displaySchemaChanges(incompatible);
|
|
29
36
|
return incompatible.diffs;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
|
-
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema is up to date.`);
|
|
33
39
|
return [];
|
|
34
40
|
}
|
|
35
41
|
exports.diffSchema = diffSchema;
|
|
36
42
|
async function migrateSchema(args) {
|
|
37
43
|
const { options, schema, allowNonInteractiveMigration, validateOnly } = args;
|
|
38
44
|
const { serviceName, instanceId, instanceName, databaseId } = getIdentifiers(schema);
|
|
39
|
-
await ensureServiceIsConnectedToCloudSql(serviceName, instanceName, databaseId);
|
|
45
|
+
await ensureServiceIsConnectedToCloudSql(serviceName, instanceName, databaseId, true);
|
|
40
46
|
try {
|
|
41
47
|
await (0, client_1.upsertSchema)(schema, validateOnly);
|
|
42
48
|
logger_1.logger.debug(`Database schema was up to date for ${instanceId}:${databaseId}`);
|
|
43
49
|
}
|
|
44
50
|
catch (err) {
|
|
51
|
+
if (err.status !== 400) {
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
45
54
|
const incompatible = errors.getIncompatibleSchemaError(err);
|
|
46
55
|
const invalidConnectors = errors.getInvalidConnectors(err);
|
|
47
56
|
if (!incompatible && !invalidConnectors.length) {
|
|
48
57
|
throw err;
|
|
49
58
|
}
|
|
50
|
-
const shouldDeleteInvalidConnectors = await promptForInvalidConnectorError(options, invalidConnectors, validateOnly);
|
|
51
|
-
if (!shouldDeleteInvalidConnectors && invalidConnectors.length) {
|
|
52
|
-
const cmd = suggestedCommand(serviceName, invalidConnectors);
|
|
53
|
-
throw new error_1.FirebaseError(`Command aborted. Try deploying compatible connectors first with ${clc.bold(cmd)}`);
|
|
54
|
-
}
|
|
59
|
+
const shouldDeleteInvalidConnectors = await promptForInvalidConnectorError(options, serviceName, invalidConnectors, validateOnly);
|
|
55
60
|
const migrationMode = incompatible
|
|
56
61
|
? await promptForSchemaMigration(options, databaseId, incompatible, allowNonInteractiveMigration)
|
|
57
62
|
: "none";
|
|
@@ -68,10 +73,12 @@ async function migrateSchema(args) {
|
|
|
68
73
|
choice: migrationMode,
|
|
69
74
|
});
|
|
70
75
|
}
|
|
71
|
-
if (
|
|
76
|
+
if (shouldDeleteInvalidConnectors) {
|
|
72
77
|
await deleteInvalidConnectors(invalidConnectors);
|
|
73
78
|
}
|
|
74
|
-
|
|
79
|
+
if (!validateOnly) {
|
|
80
|
+
await (0, client_1.upsertSchema)(schema, validateOnly);
|
|
81
|
+
}
|
|
75
82
|
return diffs;
|
|
76
83
|
}
|
|
77
84
|
return [];
|
|
@@ -169,20 +176,26 @@ async function promptForSchemaMigration(options, databaseName, err, allowNonInte
|
|
|
169
176
|
return "none";
|
|
170
177
|
}
|
|
171
178
|
}
|
|
172
|
-
async function promptForInvalidConnectorError(options, invalidConnectors, validateOnly) {
|
|
179
|
+
async function promptForInvalidConnectorError(options, serviceName, invalidConnectors, validateOnly) {
|
|
173
180
|
if (!invalidConnectors.length) {
|
|
174
181
|
return false;
|
|
175
182
|
}
|
|
176
183
|
displayInvalidConnectors(invalidConnectors);
|
|
177
184
|
if (validateOnly) {
|
|
178
|
-
|
|
185
|
+
if (options.force) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
throw new error_1.FirebaseError(`Command aborted. If you'd like to migrate it anyway, you may override with --force.`);
|
|
189
|
+
}
|
|
190
|
+
if (options.force) {
|
|
191
|
+
return true;
|
|
179
192
|
}
|
|
180
|
-
|
|
181
|
-
(
|
|
182
|
-
(await (0, prompt_1.confirm)(Object.assign(Object.assign({}, options), { message: "Would you like to delete and recreate these connectors?" }))))) {
|
|
193
|
+
if (!options.nonInteractive &&
|
|
194
|
+
(await (0, prompt_1.confirm)(Object.assign(Object.assign({}, options), { message: `Would you like to delete and recreate these connectors? This will cause ${clc.red(`downtime.`)}.` })))) {
|
|
183
195
|
return true;
|
|
184
196
|
}
|
|
185
|
-
|
|
197
|
+
const cmd = suggestedCommand(serviceName, invalidConnectors);
|
|
198
|
+
throw new error_1.FirebaseError(`Command aborted. Try deploying those connectors first with ${clc.bold(cmd)}`);
|
|
186
199
|
}
|
|
187
200
|
async function deleteInvalidConnectors(invalidConnectors) {
|
|
188
201
|
return Promise.all(invalidConnectors.map(client_1.deleteConnector));
|
|
@@ -190,39 +203,48 @@ async function deleteInvalidConnectors(invalidConnectors) {
|
|
|
190
203
|
function displayInvalidConnectors(invalidConnectors) {
|
|
191
204
|
const connectorIds = invalidConnectors.map((i) => i.split("/").pop()).join(", ");
|
|
192
205
|
(0, utils_1.logLabeledWarning)("dataconnect", `The schema you are deploying is incompatible with the following existing connectors: ${connectorIds}.`);
|
|
193
|
-
(0, utils_1.logLabeledWarning)("dataconnect", `This is a ${clc.red("breaking")} change and
|
|
206
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `This is a ${clc.red("breaking")} change and may break existing apps.`);
|
|
194
207
|
}
|
|
195
|
-
async function ensureServiceIsConnectedToCloudSql(serviceName, instanceId, databaseId) {
|
|
208
|
+
async function ensureServiceIsConnectedToCloudSql(serviceName, instanceId, databaseId, linkIfNotConnected) {
|
|
196
209
|
let currentSchema;
|
|
197
210
|
try {
|
|
198
211
|
currentSchema = await (0, client_1.getSchema)(serviceName);
|
|
199
212
|
}
|
|
200
213
|
catch (err) {
|
|
201
|
-
if (err.status
|
|
202
|
-
currentSchema = {
|
|
203
|
-
name: `${serviceName}/schemas/${types_1.SCHEMA_ID}`,
|
|
204
|
-
source: {
|
|
205
|
-
files: [],
|
|
206
|
-
},
|
|
207
|
-
primaryDatasource: {
|
|
208
|
-
postgresql: {
|
|
209
|
-
database: databaseId,
|
|
210
|
-
cloudSql: {
|
|
211
|
-
instance: instanceId,
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
214
|
+
if (err.status !== 404) {
|
|
218
215
|
throw err;
|
|
219
216
|
}
|
|
217
|
+
if (!linkIfNotConnected) {
|
|
218
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `Not yet linked to the Cloud SQL instance.`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
(0, utils_1.logLabeledBullet)("dataconnect", `Linking the Cloud SQL instance...`);
|
|
222
|
+
currentSchema = {
|
|
223
|
+
name: `${serviceName}/schemas/${types_1.SCHEMA_ID}`,
|
|
224
|
+
source: {
|
|
225
|
+
files: [],
|
|
226
|
+
},
|
|
227
|
+
primaryDatasource: {
|
|
228
|
+
postgresql: {
|
|
229
|
+
database: databaseId,
|
|
230
|
+
cloudSql: {
|
|
231
|
+
instance: instanceId,
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
220
236
|
}
|
|
221
|
-
|
|
222
|
-
|
|
237
|
+
const postgresql = currentSchema.primaryDatasource.postgresql;
|
|
238
|
+
if ((postgresql === null || postgresql === void 0 ? void 0 : postgresql.cloudSql.instance) !== instanceId) {
|
|
239
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `Switching connected Cloud SQL instance\nFrom ${postgresql === null || postgresql === void 0 ? void 0 : postgresql.cloudSql.instance}\nTo ${instanceId}`);
|
|
240
|
+
}
|
|
241
|
+
if ((postgresql === null || postgresql === void 0 ? void 0 : postgresql.database) !== databaseId) {
|
|
242
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `Switching connected Postgres database from ${postgresql === null || postgresql === void 0 ? void 0 : postgresql.database} to ${databaseId}`);
|
|
243
|
+
}
|
|
244
|
+
if (!postgresql || postgresql.schemaValidation === "STRICT") {
|
|
223
245
|
return;
|
|
224
246
|
}
|
|
225
|
-
|
|
247
|
+
postgresql.schemaValidation = "STRICT";
|
|
226
248
|
try {
|
|
227
249
|
await (0, client_1.upsertSchema)(currentSchema, false);
|
|
228
250
|
}
|
|
@@ -234,10 +256,27 @@ async function ensureServiceIsConnectedToCloudSql(serviceName, instanceId, datab
|
|
|
234
256
|
}
|
|
235
257
|
}
|
|
236
258
|
function displaySchemaChanges(error) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
259
|
+
switch (error.violationType) {
|
|
260
|
+
case "INCOMPATIBLE_SCHEMA":
|
|
261
|
+
{
|
|
262
|
+
const message = "Your new schema is incompatible with the schema of your CloudSQL database. " +
|
|
263
|
+
"The following SQL statements will migrate your database schema to match your new Data Connect schema.\n" +
|
|
264
|
+
error.diffs.map(toString).join("\n");
|
|
265
|
+
(0, utils_1.logLabeledWarning)("dataconnect", message);
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
case "INACCESSIBLE_SCHEMA":
|
|
269
|
+
{
|
|
270
|
+
const message = "Cannot access your CloudSQL database to validate schema. " +
|
|
271
|
+
"The following SQL statements can setup a new database schema.\n" +
|
|
272
|
+
error.diffs.map(toString).join("\n");
|
|
273
|
+
(0, utils_1.logLabeledWarning)("dataconnect", message);
|
|
274
|
+
(0, utils_1.logLabeledWarning)("dataconnect", "Some SQL resources may already exist.");
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
default:
|
|
278
|
+
throw new error_1.FirebaseError(`Unknown schema violation type: ${error.violationType}, IncompatibleSqlSchemaError: ${error}`);
|
|
279
|
+
}
|
|
241
280
|
}
|
|
242
281
|
function toString(diff) {
|
|
243
282
|
return `\/** ${diff.destructive ? clc.red("Destructive: ") : ""}${diff.description}*\/\n${(0, sql_formatter_1.format)(diff.sql, { language: "postgresql" })}`;
|
|
@@ -11,6 +11,7 @@ const api = require("../../.../../../../api");
|
|
|
11
11
|
const v1alpha1 = require("./v1alpha1");
|
|
12
12
|
const error_1 = require("../../../../error");
|
|
13
13
|
exports.readFileAsync = (0, util_1.promisify)(fs.readFile);
|
|
14
|
+
const TIMEOUT_OVERRIDE_ENV_VAR = "FUNCTIONS_DISCOVERY_TIMEOUT";
|
|
14
15
|
function yamlToBuild(yaml, project, region, runtime) {
|
|
15
16
|
try {
|
|
16
17
|
if (!yaml.specVersion) {
|
|
@@ -50,7 +51,7 @@ async function detectFromPort(port, project, runtime, timeout = 10000) {
|
|
|
50
51
|
const timedOut = new Promise((resolve, reject) => {
|
|
51
52
|
setTimeout(() => {
|
|
52
53
|
reject(new error_1.FirebaseError("User code failed to load. Cannot determine backend specification"));
|
|
53
|
-
}, timeout);
|
|
54
|
+
}, +(process.env[TIMEOUT_OVERRIDE_ENV_VAR] || 0) * 1000 || timeout);
|
|
54
55
|
});
|
|
55
56
|
while (true) {
|
|
56
57
|
try {
|
|
@@ -35,9 +35,9 @@ const EMULATOR_UPDATE_DETAILS = {
|
|
|
35
35
|
ui: experiments.isEnabled("emulatoruisnapshot")
|
|
36
36
|
? { version: "SNAPSHOT", expectedSize: -1, expectedChecksum: "" }
|
|
37
37
|
: {
|
|
38
|
-
version: "1.
|
|
39
|
-
expectedSize:
|
|
40
|
-
expectedChecksum: "
|
|
38
|
+
version: "1.12.1",
|
|
39
|
+
expectedSize: 3498269,
|
|
40
|
+
expectedChecksum: "a7f4398a00e5ca22abdcd78dc3877d00",
|
|
41
41
|
},
|
|
42
42
|
pubsub: {
|
|
43
43
|
version: "0.8.2",
|
|
@@ -16,7 +16,7 @@ async function execute(sqlStatements, opts) {
|
|
|
16
16
|
const user = await cloudSqlAdminClient.getUser(opts.projectId, opts.instanceId, opts.username);
|
|
17
17
|
const connectionName = instance.connectionName;
|
|
18
18
|
if (!connectionName) {
|
|
19
|
-
throw new error_1.FirebaseError(`Could not get instance
|
|
19
|
+
throw new error_1.FirebaseError(`Could not get instance connection string for ${opts.instanceId}:${opts.databaseId}`);
|
|
20
20
|
}
|
|
21
21
|
let connector;
|
|
22
22
|
let pool;
|
|
@@ -30,7 +30,7 @@ async function execute(sqlStatements, opts) {
|
|
|
30
30
|
ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
|
|
31
31
|
authType: cloud_sql_connector_1.AuthTypes.IAM,
|
|
32
32
|
});
|
|
33
|
-
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId
|
|
33
|
+
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId }));
|
|
34
34
|
break;
|
|
35
35
|
}
|
|
36
36
|
case "CLOUD_IAM_SERVICE_ACCOUNT": {
|
|
@@ -40,7 +40,7 @@ async function execute(sqlStatements, opts) {
|
|
|
40
40
|
ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
|
|
41
41
|
authType: cloud_sql_connector_1.AuthTypes.IAM,
|
|
42
42
|
});
|
|
43
|
-
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId
|
|
43
|
+
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, database: opts.databaseId }));
|
|
44
44
|
break;
|
|
45
45
|
}
|
|
46
46
|
default: {
|
|
@@ -54,19 +54,22 @@ async function execute(sqlStatements, opts) {
|
|
|
54
54
|
instanceConnectionName: connectionName,
|
|
55
55
|
ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
|
|
56
56
|
});
|
|
57
|
-
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, password: opts.password, database: opts.databaseId
|
|
57
|
+
pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: opts.username, password: opts.password, database: opts.databaseId }));
|
|
58
58
|
break;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
const conn = await pool.connect();
|
|
62
|
+
logFn(`Logged in as ${opts.username}`);
|
|
61
63
|
for (const s of sqlStatements) {
|
|
62
|
-
logFn(`Executing: '${s}'
|
|
64
|
+
logFn(`Executing: '${s}'`);
|
|
63
65
|
try {
|
|
64
|
-
await
|
|
66
|
+
await conn.query(s);
|
|
65
67
|
}
|
|
66
68
|
catch (err) {
|
|
67
69
|
throw new error_1.FirebaseError(`Error executing ${err}`);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
72
|
+
conn.release();
|
|
70
73
|
await pool.end();
|
|
71
74
|
connector.close();
|
|
72
75
|
}
|
package/lib/requireAuth.js
CHANGED
|
@@ -20,6 +20,9 @@ function getAuthClient(config) {
|
|
|
20
20
|
return authClient;
|
|
21
21
|
}
|
|
22
22
|
async function autoAuth(options, authScopes) {
|
|
23
|
+
if (process.env.MONOSPACE_ENV) {
|
|
24
|
+
throw new error_1.FirebaseError("autoAuth not yet implemented for IDX. Please run 'firebase login'");
|
|
25
|
+
}
|
|
23
26
|
const client = getAuthClient({ scopes: authScopes, projectId: options.project });
|
|
24
27
|
const token = await client.getAccessToken();
|
|
25
28
|
token !== null ? apiv2.setAccessToken(token) : false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-tools",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.10.0",
|
|
4
4
|
"description": "Command-Line Interface for Firebase",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@google-cloud/cloud-sql-connector": "^1.2.3",
|
|
62
|
-
"@google-cloud/pubsub": "^
|
|
62
|
+
"@google-cloud/pubsub": "^4.4.0",
|
|
63
63
|
"abort-controller": "^3.0.0",
|
|
64
64
|
"ajv": "^6.12.6",
|
|
65
65
|
"archiver": "^5.0.0",
|