firebase-tools 13.8.3 → 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.
@@ -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}?force=true`);
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
- var _a, _b;
9
- const original = ((_b = (_a = err.context) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) || err.orignal;
10
- if (!original) {
11
- throw err;
8
+ const incompatibles = errorDetails(err, INCOMPATIBLE_SCHEMA_ERROR_TYPESTRING);
9
+ if (incompatibles.length === 0) {
10
+ return undefined;
12
11
  }
13
- const details = original.details;
14
- const incompatibles = details.filter((d) => { var _a; return (_a = d["@type"]) === null || _a === void 0 ? void 0 : _a.includes(INCOMPATIBLE_SCHEMA_ERROR_TYPESTRING); });
15
- return incompatibles[0];
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, _c, _d;
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 = (_c = preconditionErr === null || preconditionErr === void 0 ? void 0 : preconditionErr.violations) === null || _c === void 0 ? void 0 : _c.filter((v) => v.type === INCOMPATIBLE_CONNECTOR_TYPE);
26
- const newConns = (_d = incompatibleConnViolation === null || incompatibleConnViolation === void 0 ? void 0 : incompatibleConnViolation.map((i) => i.subject)) !== null && _d !== void 0 ? _d : [];
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.checkInstanceConfig = exports.provisionCloudSql = void 0;
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
- if (!checkInstanceConfig(existingInstance, enableGoogleMlIntegration)) {
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 to enable Cloud IAM authentication and public IP. This may take a few minutes...`);
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
- silent ||
48
- utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found, creating it now...`);
49
- await cloudSqlAdminClient.createDatabase(projectId, instanceId, databaseId);
50
- silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} created.`);
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 checkInstanceConfig(instance, requireGoogleMlIntegration) {
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
- return false;
70
+ reason += "\n - to enable public IP.";
63
71
  }
64
72
  if (requireGoogleMlIntegration) {
65
73
  if (!settings.enableGoogleMlIntegration) {
66
- return false;
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
- return false;
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
- return isIamEnabled;
81
+ if (!isIamEnabled) {
82
+ reason += "\n - to enable IAM authentication database flag.";
83
+ }
84
+ return reason;
74
85
  }
75
- exports.checkInstanceConfig = checkInstanceConfig;
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 (invalidConnectors.length) {
76
+ if (shouldDeleteInvalidConnectors) {
72
77
  await deleteInvalidConnectors(invalidConnectors);
73
78
  }
74
- await (0, client_1.upsertSchema)(schema, validateOnly);
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
- return false;
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
- else if (options.force ||
181
- (!options.nonInteractive &&
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
- return false;
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 will cause a brief downtime.`);
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 === 404) {
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
- if (!currentSchema.primaryDatasource.postgresql ||
222
- currentSchema.primaryDatasource.postgresql.schemaValidation === "STRICT") {
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
- currentSchema.primaryDatasource.postgresql.schemaValidation = "STRICT";
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
- const message = "Your new schema is incompatible with the schema of your CloudSQL database. " +
238
- "The following SQL statements will migrate your database schema to match your new Data Connect schema.\n" +
239
- error.diffs.map(toString).join("\n");
240
- (0, utils_1.logLabeledWarning)("dataconnect", message);
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.11.8",
39
- expectedSize: 3523907,
40
- expectedChecksum: "49f6dc1911dda9d10df62a6c09aaf9a0",
38
+ version: "1.12.1",
39
+ expectedSize: 3498269,
40
+ expectedChecksum: "a7f4398a00e5ca22abdcd78dc3877d00",
41
41
  },
42
42
  pubsub: {
43
43
  version: "0.8.2",
@@ -88,7 +88,7 @@ exports.ALL_EXPERIMENTS = experiments({
88
88
  },
89
89
  apphosting: {
90
90
  shortDescription: "Allow CLI option for Frameworks",
91
- default: false,
91
+ default: true,
92
92
  public: false,
93
93
  },
94
94
  dataconnect: {
@@ -99,6 +99,7 @@ exports.ALL_EXPERIMENTS = experiments({
99
99
  genkit: {
100
100
  shortDescription: "Enable Genkit related features.",
101
101
  fullDescription: "Enable Genkit related features.",
102
+ default: true,
102
103
  public: false,
103
104
  },
104
105
  });
@@ -231,7 +231,6 @@ async function getProductionDistDirFiles(sourceDir, distDir) {
231
231
  cwd: (0, path_1.join)(sourceDir, distDir),
232
232
  nodir: true,
233
233
  absolute: false,
234
- realpath: utils_2.IS_WINDOWS,
235
234
  }, (err, matches) => {
236
235
  if (err)
237
236
  reject(err);
@@ -42,6 +42,8 @@ async function createInstance(projectId, location, instanceId, enableGoogleMlInt
42
42
  userLabels: { "firebase-data-connect": "ft" },
43
43
  insightsConfig: {
44
44
  queryInsightsEnabled: true,
45
+ queryPlansPerMinute: 5,
46
+ queryStringLength: 1024,
45
47
  },
46
48
  },
47
49
  });
@@ -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 conection string for ${opts.instanceId}:${opts.databaseId}`);
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, max: 1 }));
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, max: 1 }));
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, max: 1 }));
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}' as ${opts.username}`);
64
+ logFn(`Executing: '${s}'`);
63
65
  try {
64
- await pool.query(s);
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
  }
@@ -10,7 +10,6 @@ const logger_1 = require("./logger");
10
10
  const utils = require("./utils");
11
11
  const scopes = require("./scopes");
12
12
  const auth_1 = require("./auth");
13
- const monospace_1 = require("./monospace");
14
13
  const AUTH_ERROR_MESSAGE = `Command requires authentication, please run ${clc.bold("firebase login")}`;
15
14
  let authClient;
16
15
  function getAuthClient(config) {
@@ -21,6 +20,9 @@ function getAuthClient(config) {
21
20
  return authClient;
22
21
  }
23
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
+ }
24
26
  const client = getAuthClient({ scopes: authScopes, projectId: options.project });
25
27
  const token = await client.getAccessToken();
26
28
  token !== null ? apiv2.setAccessToken(token) : false;
@@ -32,13 +34,6 @@ async function autoAuth(options, authScopes) {
32
34
  catch (e) {
33
35
  logger_1.logger.debug(`Error getting account credentials.`);
34
36
  }
35
- if (!options.isVSCE && (0, monospace_1.isMonospaceEnv)()) {
36
- await (0, monospace_1.selectProjectInMonospace)({
37
- projectRoot: options.config.projectDir,
38
- project: options.project,
39
- isVSCE: options.isVSCE,
40
- });
41
- }
42
37
  return clientEmail;
43
38
  }
44
39
  async function requireAuth(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "13.8.3",
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": "^3.0.1",
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",
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isMonospaceEnv = exports.selectProjectInMonospace = void 0;
4
- const node_fetch_1 = require("node-fetch");
5
- const error_1 = require("../error");
6
- const logger_1 = require("../logger");
7
- const rc_1 = require("../rc");
8
- const POLL_USER_RESPONSE_MILLIS = 2000;
9
- async function selectProjectInMonospace({ projectRoot, project, isVSCE, }) {
10
- const initFirebaseResponse = await initFirebase(project);
11
- if (initFirebaseResponse.success === false) {
12
- throw new Error(String(initFirebaseResponse.error));
13
- }
14
- const { rid } = initFirebaseResponse;
15
- const authorizedProject = await pollAuthorizedProject(rid);
16
- if (!authorizedProject)
17
- return null;
18
- if (isVSCE)
19
- return authorizedProject;
20
- if (projectRoot)
21
- createFirebaseRc(projectRoot, authorizedProject);
22
- }
23
- exports.selectProjectInMonospace = selectProjectInMonospace;
24
- async function pollAuthorizedProject(rid) {
25
- const getInitFirebaseRes = await getInitFirebaseResponse(rid);
26
- if ("userResponse" in getInitFirebaseRes) {
27
- if (getInitFirebaseRes.userResponse.success) {
28
- return getInitFirebaseRes.userResponse.projectId;
29
- }
30
- return null;
31
- }
32
- const { error } = getInitFirebaseRes;
33
- if (error === "WAITING_FOR_RESPONSE") {
34
- await new Promise((res) => setTimeout(res, POLL_USER_RESPONSE_MILLIS));
35
- return pollAuthorizedProject(rid);
36
- }
37
- if (error === "USER_CANCELED") {
38
- throw new error_1.FirebaseError("User canceled without authorizing any project");
39
- }
40
- throw new error_1.FirebaseError(`Unhandled /get-init-firebase-response error`, {
41
- original: new Error(error),
42
- });
43
- }
44
- async function initFirebase(project) {
45
- const port = getMonospaceDaemonPort();
46
- if (!port)
47
- throw new error_1.FirebaseError("Undefined MONOSPACE_DAEMON_PORT");
48
- const initFirebaseURL = new URL(`http://localhost:${port}/init-firebase`);
49
- if (project) {
50
- initFirebaseURL.searchParams.set("known_project", project);
51
- }
52
- const initFirebaseRes = await (0, node_fetch_1.default)(initFirebaseURL.toString(), {
53
- method: "POST",
54
- headers: {
55
- "Content-Type": "application/json",
56
- },
57
- });
58
- const initFirebaseResponse = (await initFirebaseRes.json());
59
- return initFirebaseResponse;
60
- }
61
- async function getInitFirebaseResponse(rid) {
62
- const port = getMonospaceDaemonPort();
63
- if (!port)
64
- throw new error_1.FirebaseError("Undefined MONOSPACE_DAEMON_PORT");
65
- const getInitFirebaseRes = await (0, node_fetch_1.default)(`http://localhost:${port}/get-init-firebase-response?rid=${rid}`);
66
- const getInitFirebaseJson = (await getInitFirebaseRes.json());
67
- logger_1.logger.debug(`/get-init-firebase-response?rid=${rid} response:`);
68
- logger_1.logger.debug(getInitFirebaseJson);
69
- return getInitFirebaseJson;
70
- }
71
- function createFirebaseRc(projectDir, authorizedProject) {
72
- const firebaseRc = (0, rc_1.loadRC)({ cwd: projectDir });
73
- firebaseRc.addProjectAlias("default", authorizedProject);
74
- return firebaseRc.save();
75
- }
76
- function isMonospaceEnv() {
77
- return getMonospaceDaemonPort() !== undefined;
78
- }
79
- exports.isMonospaceEnv = isMonospaceEnv;
80
- function getMonospaceDaemonPort() {
81
- return process.env.MONOSPACE_DAEMON_PORT;
82
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });