firebase-tools 13.11.3 → 13.12.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.
Files changed (41) hide show
  1. package/lib/auth.js +14 -15
  2. package/lib/commands/dataconnect-sdk-generate.js +4 -3
  3. package/lib/commands/ext-dev-init.js +25 -26
  4. package/lib/commands/index.js +9 -11
  5. package/lib/commands/init.js +13 -11
  6. package/lib/config.js +6 -1
  7. package/lib/crashlytics/buildToolsJarHelper.js +1 -1
  8. package/lib/dataconnect/client.js +1 -1
  9. package/lib/dataconnect/fileUtils.js +8 -6
  10. package/lib/dataconnect/load.js +4 -3
  11. package/lib/deploy/dataconnect/prepare.js +1 -1
  12. package/lib/emulator/controller.js +0 -4
  13. package/lib/emulator/dataconnectEmulator.js +111 -13
  14. package/lib/emulator/downloadableEmulators.js +0 -1
  15. package/lib/emulator/hub.js +1 -1
  16. package/lib/emulator/portUtils.js +9 -0
  17. package/lib/emulator/storage/rules/config.js +4 -2
  18. package/lib/experiments.js +2 -2
  19. package/lib/hosting/implicitInit.js +2 -2
  20. package/lib/init/features/dataconnect/index.js +12 -11
  21. package/lib/init/features/dataconnect/sdk.js +120 -0
  22. package/lib/init/features/firestore/indexes.js +2 -2
  23. package/lib/init/features/firestore/rules.js +2 -2
  24. package/lib/init/features/functions/javascript.js +6 -8
  25. package/lib/init/features/functions/python.js +4 -6
  26. package/lib/init/features/functions/typescript.js +8 -10
  27. package/lib/init/features/hosting/index.js +3 -3
  28. package/lib/init/features/index.js +3 -1
  29. package/lib/init/features/storage.js +2 -2
  30. package/lib/init/index.js +1 -0
  31. package/lib/listFiles.js +1 -0
  32. package/lib/management/apps.js +2 -2
  33. package/lib/templates.js +23 -0
  34. package/lib/utils.js +2 -2
  35. package/package.json +1 -1
  36. package/schema/connector-yaml.json +36 -4
  37. package/schema/dataconnect-yaml.json +4 -0
  38. package/schema/firebase-config.json +0 -8
  39. package/templates/_gitignore +3 -0
  40. package/templates/init/dataconnect/connector.yaml +11 -0
  41. package/templates/init/dataconnect/dataconnect.yaml +1 -0
package/lib/auth.js CHANGED
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addAdditionalAccount = exports.logout = exports.getAccessToken = exports.findAccountByEmail = exports.loginGithub = exports.loginGoogle = exports.setGlobalDefaultAccount = exports.setProjectAccount = exports.loginAdditionalAccount = exports.selectAccount = exports.setRefreshToken = exports.setActiveAccount = exports.getAllAccounts = exports.getAdditionalAccounts = exports.getProjectDefaultAccount = exports.getGlobalDefaultAccount = void 0;
4
4
  const clc = require("colorette");
5
5
  const FormData = require("form-data");
6
- const fs = require("fs");
7
6
  const http = require("http");
8
7
  const jwt = require("jsonwebtoken");
9
8
  const opn = require("open");
10
- const path = require("path");
11
9
  const portfinder = require("portfinder");
12
10
  const url = require("url");
13
- const util = require("util");
14
11
  const apiv2 = require("./apiv2");
15
12
  const configstore_1 = require("./configstore");
16
13
  const error_1 = require("./error");
@@ -23,6 +20,7 @@ const uuid_1 = require("uuid");
23
20
  const crypto_1 = require("crypto");
24
21
  const track_1 = require("./track");
25
22
  const api_1 = require("./api");
23
+ const templates_1 = require("./templates");
26
24
  portfinder.setBasePort(9005);
27
25
  function getGlobalDefaultAccount() {
28
26
  const user = configstore_1.configstore.get("user");
@@ -261,13 +259,12 @@ async function getGithubTokensFromAuthorizationCode(code, callbackUrl) {
261
259
  });
262
260
  return res.body.access_token;
263
261
  }
264
- async function respondWithFile(req, res, statusCode, filename) {
265
- const response = await util.promisify(fs.readFile)(path.join(__dirname, filename));
262
+ function respondHtml(req, res, statusCode, html) {
266
263
  res.writeHead(statusCode, {
267
- "Content-Length": response.length,
264
+ "Content-Length": html.length,
268
265
  "Content-Type": "text/html",
269
266
  });
270
- res.end(response);
267
+ res.end(html);
271
268
  req.socket.destroy();
272
269
  }
273
270
  function urlsafeBase64(base64string) {
@@ -319,8 +316,8 @@ async function loginRemotely() {
319
316
  async function loginWithLocalhostGoogle(port, userHint) {
320
317
  const callbackUrl = getCallbackUrl(port);
321
318
  const authUrl = getLoginUrl(callbackUrl, userHint);
322
- const successTemplate = "../templates/loginSuccess.html";
323
- const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successTemplate, getTokensFromAuthorizationCode);
319
+ const successHtml = await (0, templates_1.readTemplate)("loginSuccess.html");
320
+ const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getTokensFromAuthorizationCode);
324
321
  void (0, track_1.trackGA4)("login", { method: "google_localhost" });
325
322
  return {
326
323
  user: jwt.decode(tokens.id_token, { json: true }),
@@ -331,30 +328,32 @@ async function loginWithLocalhostGoogle(port, userHint) {
331
328
  async function loginWithLocalhostGitHub(port) {
332
329
  const callbackUrl = getCallbackUrl(port);
333
330
  const authUrl = getGithubLoginUrl(callbackUrl);
334
- const successTemplate = "../templates/loginSuccessGithub.html";
335
- const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successTemplate, getGithubTokensFromAuthorizationCode);
331
+ const successHtml = await (0, templates_1.readTemplate)("loginSuccessGithub.html");
332
+ const tokens = await loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getGithubTokensFromAuthorizationCode);
336
333
  void (0, track_1.trackGA4)("login", { method: "github_localhost" });
337
334
  return tokens;
338
335
  }
339
- async function loginWithLocalhost(port, callbackUrl, authUrl, successTemplate, getTokens) {
336
+ async function loginWithLocalhost(port, callbackUrl, authUrl, successHtml, getTokens) {
340
337
  return new Promise((resolve, reject) => {
341
338
  const server = http.createServer(async (req, res) => {
342
339
  const query = url.parse(`${req.url}`, true).query || {};
343
340
  const queryState = query.state;
344
341
  const queryCode = query.code;
345
342
  if (queryState !== _nonce || typeof queryCode !== "string") {
346
- await respondWithFile(req, res, 400, "../templates/loginFailure.html");
343
+ const html = await (0, templates_1.readTemplate)("loginFailure.html");
344
+ respondHtml(req, res, 400, html);
347
345
  reject(new error_1.FirebaseError("Unexpected error while logging in"));
348
346
  server.close();
349
347
  return;
350
348
  }
351
349
  try {
352
350
  const tokens = await getTokens(queryCode, callbackUrl);
353
- await respondWithFile(req, res, 200, successTemplate);
351
+ respondHtml(req, res, 200, successHtml);
354
352
  resolve(tokens);
355
353
  }
356
354
  catch (err) {
357
- await respondWithFile(req, res, 400, "../templates/loginFailure.html");
355
+ const html = await (0, templates_1.readTemplate)("loginFailure.html");
356
+ respondHtml(req, res, 400, html);
358
357
  reject(err);
359
358
  }
360
359
  server.close();
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const path = require("path");
5
+ const clc = require("colorette");
5
6
  const command_1 = require("../command");
6
7
  const dataconnectEmulator_1 = require("../emulator/dataconnectEmulator");
7
8
  const projectUtils_1 = require("../projectUtils");
@@ -19,7 +20,7 @@ exports.command = new command_1.Command("dataconnect:sdk:generate")
19
20
  const cwd = options.cwd || process.cwd();
20
21
  configDir = path.resolve(path.join(cwd), configDir);
21
22
  }
22
- const serviceInfo = await (0, load_1.load)(projectId, service.location, configDir);
23
+ const serviceInfo = await (0, load_1.load)(projectId, configDir);
23
24
  const hasGeneratables = serviceInfo.connectorInfo.some((c) => {
24
25
  var _a, _b, _c;
25
26
  return (((_a = c.connectorYaml.generate) === null || _a === void 0 ? void 0 : _a.javascriptSdk) ||
@@ -28,13 +29,13 @@ exports.command = new command_1.Command("dataconnect:sdk:generate")
28
29
  });
29
30
  if (!hasGeneratables) {
30
31
  logger_1.logger.warn("No generated SDKs have been declared in connector.yaml files.");
31
- logger_1.logger.warn("See https://firebase.google.com/docs/data-connect/quickstart#configure-sdk-outputs for examples of how to configure generated SDKs.");
32
+ logger_1.logger.warn(`Run ${clc.bold("firebase init dataconnect:sdk")} to configure a generated SDK.`);
33
+ logger_1.logger.warn(`See https://firebase.google.com/docs/data-connect/gp/web-sdk for more details of how to configure generated SDKs.`);
32
34
  return;
33
35
  }
34
36
  for (const conn of serviceInfo.connectorInfo) {
35
37
  const output = await dataconnectEmulator_1.DataConnectEmulator.generate({
36
38
  configDir,
37
- locationId: service.location,
38
39
  connectorId: conn.connectorYaml.connectorId,
39
40
  });
40
41
  logger_1.logger.info(output);
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const fs = require("fs");
5
- const path = require("path");
6
4
  const marked_1 = require("marked");
7
5
  const TerminalRenderer = require("marked-terminal");
8
6
  const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
@@ -12,19 +10,18 @@ const error_1 = require("../error");
12
10
  const prompt_1 = require("../prompt");
13
11
  const logger_1 = require("../logger");
14
12
  const npmDependencies = require("../init/features/functions/npm-dependencies");
13
+ const templates_1 = require("../templates");
15
14
  marked_1.marked.setOptions({
16
15
  renderer: new TerminalRenderer(),
17
16
  });
18
- const TEMPLATE_ROOT = path.resolve(__dirname, "../../templates/extensions/");
19
- const FUNCTIONS_ROOT = path.resolve(__dirname, "../../templates/init/functions/");
20
17
  function readCommonTemplates() {
21
18
  return {
22
- integrationTestFirebaseJsonTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "integration-test.json"), "utf8"),
23
- integrationTestEnvTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "integration-test.env"), "utf8"),
24
- extSpecTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "extension.yaml"), "utf8"),
25
- preinstallTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "PREINSTALL.md"), "utf8"),
26
- postinstallTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "POSTINSTALL.md"), "utf8"),
27
- changelogTemplate: fs.readFileSync(path.join(TEMPLATE_ROOT, "CL-template.md"), "utf8"),
19
+ integrationTestFirebaseJsonTemplate: (0, templates_1.readTemplateSync)("extensions/integration-test.json"),
20
+ integrationTestEnvTemplate: (0, templates_1.readTemplateSync)("extensions/integration-test.env"),
21
+ extSpecTemplate: (0, templates_1.readTemplateSync)("extensions/extension.yaml"),
22
+ preinstallTemplate: (0, templates_1.readTemplateSync)("extensions/PREINSTALL.md"),
23
+ postinstallTemplate: (0, templates_1.readTemplateSync)("extensions/POSTINSTALL.md"),
24
+ changelogTemplate: (0, templates_1.readTemplateSync)("extensions/CL-template.md"),
28
25
  };
29
26
  }
30
27
  exports.command = new command_1.Command("ext:dev:init")
@@ -34,6 +31,7 @@ exports.command = new command_1.Command("ext:dev:init")
34
31
  const cwd = options.cwd || process.cwd();
35
32
  const config = new config_1.Config({}, { projectDir: cwd, cwd: cwd });
36
33
  try {
34
+ let welcome;
37
35
  const lang = await (0, prompt_1.promptOnce)({
38
36
  type: "list",
39
37
  name: "language",
@@ -53,10 +51,12 @@ exports.command = new command_1.Command("ext:dev:init")
53
51
  switch (lang) {
54
52
  case "javascript": {
55
53
  await javascriptSelected(config);
54
+ welcome = (0, templates_1.readTemplateSync)("extensions/javascript/WELCOME.md");
56
55
  break;
57
56
  }
58
57
  case "typescript": {
59
58
  await typescriptSelected(config);
59
+ welcome = (0, templates_1.readTemplateSync)("extensions/typescript/WELCOME.md");
60
60
  break;
61
61
  }
62
62
  default: {
@@ -64,7 +64,6 @@ exports.command = new command_1.Command("ext:dev:init")
64
64
  }
65
65
  }
66
66
  await npmDependencies.askInstallDependencies({ source: "functions" }, config);
67
- const welcome = fs.readFileSync(path.join(TEMPLATE_ROOT, lang, "WELCOME.md"), "utf8");
68
67
  return logger_1.logger.info("\n" + (0, marked_1.marked)(welcome));
69
68
  }
70
69
  catch (err) {
@@ -77,15 +76,15 @@ exports.command = new command_1.Command("ext:dev:init")
77
76
  }
78
77
  });
79
78
  async function typescriptSelected(config) {
80
- const packageLintingTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "package.lint.json"), "utf8");
81
- const packageNoLintingTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "package.nolint.json"), "utf8");
82
- const tsconfigTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "tsconfig.json"), "utf8");
83
- const tsconfigDevTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "tsconfig.dev.json"), "utf8");
84
- const indexTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "index.ts"), "utf8");
85
- const integrationTestTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "integration-test.ts"), "utf8");
86
- const gitignoreTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "_gitignore"), "utf8");
87
- const mocharcTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "typescript", "_mocharc"), "utf8");
88
- const eslintTemplate = fs.readFileSync(path.join(FUNCTIONS_ROOT, "typescript", "_eslintrc"), "utf8");
79
+ const packageLintingTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/package.lint.json");
80
+ const packageNoLintingTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/package.nolint.json");
81
+ const tsconfigTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/tsconfig.json");
82
+ const tsconfigDevTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/tsconfig.dev.json");
83
+ const indexTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/index.ts");
84
+ const integrationTestTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/integration-test.ts");
85
+ const gitignoreTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/_gitignore");
86
+ const mocharcTemplate = (0, templates_1.readTemplateSync)("extensions/typescript/_mocharc");
87
+ const eslintTemplate = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
89
88
  const lint = await (0, prompt_1.promptOnce)({
90
89
  name: "lint",
91
90
  type: "confirm",
@@ -116,12 +115,12 @@ async function typescriptSelected(config) {
116
115
  await config.askWriteProjectFile("functions/.gitignore", gitignoreTemplate);
117
116
  }
118
117
  async function javascriptSelected(config) {
119
- const indexTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "javascript", "index.js"), "utf8");
120
- const integrationTestTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "javascript", "integration-test.js"), "utf8");
121
- const packageLintingTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "javascript", "package.lint.json"), "utf8");
122
- const packageNoLintingTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "javascript", "package.nolint.json"), "utf8");
123
- const gitignoreTemplate = fs.readFileSync(path.join(TEMPLATE_ROOT, "javascript", "_gitignore"), "utf8");
124
- const eslintTemplate = fs.readFileSync(path.join(FUNCTIONS_ROOT, "javascript", "_eslintrc"), "utf8");
118
+ const indexTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/index.js");
119
+ const integrationTestTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/integration-test.js");
120
+ const packageLintingTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/package.lint.json");
121
+ const packageNoLintingTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/package.nolint.json");
122
+ const gitignoreTemplate = (0, templates_1.readTemplateSync)("extensions/javascript/_gitignore");
123
+ const eslintTemplate = (0, templates_1.readTemplateSync)("init/functions/javascript/_eslintrc");
125
124
  const lint = await (0, prompt_1.promptOnce)({
126
125
  name: "lint",
127
126
  type: "confirm",
@@ -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
- if (experiments.isEnabled("dataconnect")) {
204
- client.dataconnect = {};
205
- client.setup.emulators.dataconnect = loadCommand("setup-emulators-dataconnect");
206
- client.dataconnect.services = {};
207
- client.dataconnect.services.list = loadCommand("dataconnect-services-list");
208
- client.dataconnect.sql = {};
209
- client.dataconnect.sql.diff = loadCommand("dataconnect-sql-diff");
210
- client.dataconnect.sql.migrate = loadCommand("dataconnect-sql-migrate");
211
- client.dataconnect.sdk = {};
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");
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.initAction = exports.command = void 0;
4
4
  const clc = require("colorette");
5
- const fs = require("fs");
6
5
  const os = require("os");
7
6
  const path = require("path");
8
7
  const command_1 = require("../command");
@@ -15,10 +14,10 @@ const requireAuth_1 = require("../requireAuth");
15
14
  const fsutils = require("../fsutils");
16
15
  const utils = require("../utils");
17
16
  const experiments_1 = require("../experiments");
17
+ const templates_1 = require("../templates");
18
18
  const homeDir = os.homedir();
19
- const TEMPLATE_ROOT = path.resolve(__dirname, "../../templates/");
20
- const BANNER_TEXT = fs.readFileSync(path.join(TEMPLATE_ROOT, "banner.txt"), "utf8");
21
- const GITIGNORE_TEMPLATE = fs.readFileSync(path.join(TEMPLATE_ROOT, "_gitignore"), "utf8");
19
+ const BANNER_TEXT = (0, templates_1.readTemplateSync)("banner.txt");
20
+ const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("_gitignore");
22
21
  function isOutside(from, to) {
23
22
  return !!/^\.\./.exec(path.relative(from, to));
24
23
  }
@@ -76,13 +75,16 @@ if ((0, experiments_1.isEnabled)("genkit")) {
76
75
  checked: false,
77
76
  });
78
77
  }
79
- if ((0, experiments_1.isEnabled)("dataconnect")) {
80
- choices.push({
81
- value: "dataconnect",
82
- name: "Data Connect: Set up a Firebase Data Connect service.",
83
- checked: false,
84
- });
85
- }
78
+ choices.push({
79
+ value: "dataconnect",
80
+ name: "Data Connect: Set up a Firebase Data Connect service",
81
+ checked: false,
82
+ });
83
+ choices.push({
84
+ value: "dataconnect:sdk",
85
+ name: "Data Connect: Set up a generated SDK for your Firebase Data Connect service",
86
+ checked: false,
87
+ });
86
88
  const featureNames = choices.map((choice) => choice.value);
87
89
  const DESCRIPTION = `Interactively configure the current directory as a Firebase project or initialize new features in an already configured Firebase project directory.
88
90
 
package/lib/config.js CHANGED
@@ -18,7 +18,7 @@ const loadCJSON_1 = require("./loadCJSON");
18
18
  const parseBoltRules = require("./parseBoltRules");
19
19
  class Config {
20
20
  constructor(src, options = {}) {
21
- var _a;
21
+ var _a, _b;
22
22
  this.data = {};
23
23
  this.defaults = {};
24
24
  this.notes = {};
@@ -54,6 +54,11 @@ class Config {
54
54
  }
55
55
  }
56
56
  }
57
+ if (((_b = this._src.dataconnect) === null || _b === void 0 ? void 0 : _b.location) ||
58
+ (Array.isArray(this._src.dataconnect) && this._src.dataconnect.some((c) => c === null || c === void 0 ? void 0 : c.location))) {
59
+ utils.logLabeledWarning("dataconnect", "'location' has been moved from 'firebase.json' to 'dataconnect.yaml'. " +
60
+ "Please remove 'dataconnect.location' from 'firebase.json' and add it as top level field to 'dataconnect.yaml' instead ");
61
+ }
57
62
  }
58
63
  materialize(target) {
59
64
  const val = _.get(this._src, target);
@@ -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.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
  }
@@ -11,12 +11,11 @@ function readFirebaseJson(config) {
11
11
  return [];
12
12
  }
13
13
  const validator = (cfg) => {
14
- if (!cfg["source"] && !cfg["location"]) {
15
- throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source` and `location`");
14
+ if (!cfg["source"]) {
15
+ throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source`");
16
16
  }
17
17
  return {
18
18
  source: cfg["source"],
19
- location: cfg["location"],
20
19
  };
21
20
  };
22
21
  const configs = config.get("dataconnect");
@@ -27,7 +26,7 @@ function readFirebaseJson(config) {
27
26
  return configs.map(validator);
28
27
  }
29
28
  else {
30
- throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string, location: string }");
29
+ throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string }");
31
30
  }
32
31
  }
33
32
  exports.readFirebaseJson = readFirebaseJson;
@@ -38,6 +37,9 @@ async function readDataConnectYaml(sourceDirectory) {
38
37
  }
39
38
  exports.readDataConnectYaml = readDataConnectYaml;
40
39
  function validateDataConnectYaml(unvalidated) {
40
+ if (!unvalidated["location"]) {
41
+ throw new error_1.FirebaseError("Missing required field 'location' in dataconnect.yaml");
42
+ }
41
43
  return unvalidated;
42
44
  }
43
45
  async function readConnectorYaml(sourceDirectory) {
@@ -74,13 +76,13 @@ async function pickService(projectId, config, serviceId) {
74
76
  throw new error_1.FirebaseError("No Data Connect services found in firebase.json.");
75
77
  }
76
78
  else if (serviceCfgs.length === 1) {
77
- serviceInfo = await (0, load_1.load)(projectId, serviceCfgs[0].location, serviceCfgs[0].source);
79
+ serviceInfo = await (0, load_1.load)(projectId, serviceCfgs[0].source);
78
80
  }
79
81
  else {
80
82
  if (!serviceId) {
81
83
  throw new error_1.FirebaseError("Multiple Data Connect services found in firebase.json. Please specify a service ID to use.");
82
84
  }
83
- const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, c.location, c.source)));
85
+ const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, c.source)));
84
86
  const maybe = infos.find((i) => i.dataConnectYaml.serviceId === serviceId);
85
87
  if (!maybe) {
86
88
  throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json.`);
@@ -4,9 +4,9 @@ exports.load = void 0;
4
4
  const path = require("path");
5
5
  const fileUtils = require("./fileUtils");
6
6
  const types_1 = require("./types");
7
- async function load(projectId, locationId, sourceDirectory) {
7
+ async function load(projectId, sourceDirectory) {
8
8
  const dataConnectYaml = await fileUtils.readDataConnectYaml(sourceDirectory);
9
- const serviceName = `projects/${projectId}/locations/${locationId}/services/${dataConnectYaml.serviceId}`;
9
+ const serviceName = `projects/${projectId}/locations/${dataConnectYaml.location}/services/${dataConnectYaml.serviceId}`;
10
10
  const schemaDir = path.join(sourceDirectory, dataConnectYaml.schema.source);
11
11
  const schemaGQLs = await fileUtils.readGQLFiles(schemaDir);
12
12
  const connectorInfo = await Promise.all(dataConnectYaml.connectorDirs.map(async (dir) => {
@@ -14,6 +14,7 @@ async function load(projectId, locationId, sourceDirectory) {
14
14
  const connectorYaml = await fileUtils.readConnectorYaml(connectorDir);
15
15
  const connectorGqls = await fileUtils.readGQLFiles(connectorDir);
16
16
  return {
17
+ directory: connectorDir,
17
18
  connectorYaml,
18
19
  connector: {
19
20
  name: `${serviceName}/connectors/${connectorYaml.connectorId}`,
@@ -28,7 +29,7 @@ async function load(projectId, locationId, sourceDirectory) {
28
29
  sourceDirectory,
29
30
  schema: {
30
31
  name: `${serviceName}/schemas/${types_1.SCHEMA_ID}`,
31
- primaryDatasource: (0, types_1.toDatasource)(projectId, locationId, dataConnectYaml.schema.datasource),
32
+ primaryDatasource: (0, types_1.toDatasource)(projectId, dataConnectYaml.location, dataConnectYaml.schema.datasource),
32
33
  source: {
33
34
  files: schemaGQLs,
34
35
  },
@@ -18,7 +18,7 @@ async function default_1(context, options) {
18
18
  const serviceCfgs = (0, fileUtils_1.readFirebaseJson)(options.config);
19
19
  utils.logLabeledBullet("dataconnect", `Preparing to deploy`);
20
20
  const filters = (0, filters_1.getResourceFilters)(options);
21
- const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, c.location, path.join(options.cwd || process.cwd(), c.source))));
21
+ const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, path.join(options.cwd || process.cwd(), c.source))));
22
22
  for (const si of serviceInfos) {
23
23
  si.deploymentMetadata = await (0, build_1.build)(options, si.sourceDirectory);
24
24
  }
@@ -535,13 +535,9 @@ async function startAll(options, showUI = true, runningTestScript = false) {
535
535
  projectId,
536
536
  auto_download: true,
537
537
  configDir,
538
- locationId: config[0].location,
539
538
  rc: options.rc,
540
539
  });
541
540
  await startEmulator(dataConnectEmulator);
542
- if (!utils.isVSCodeExtension()) {
543
- await dataConnectEmulator.connectToPostgres();
544
- }
545
541
  }
546
542
  if (listenForEmulator.storage) {
547
543
  const storageAddr = legacyGetFirstAddr(types_1.Emulators.STORAGE);