firebase-tools 13.7.5 → 13.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/lib/api.js +9 -1
  2. package/lib/apiv2.js +19 -13
  3. package/lib/apphosting/app.js +38 -58
  4. package/lib/apphosting/githubConnections.js +1 -1
  5. package/lib/apphosting/index.js +72 -20
  6. package/lib/checkValidTargetFilters.js +8 -1
  7. package/lib/commands/apphosting-backends-create.js +4 -3
  8. package/lib/commands/apphosting-backends-delete.js +24 -17
  9. package/lib/commands/apphosting-backends-list.js +3 -3
  10. package/lib/commands/apphosting-secrets-grantaccess.js +9 -5
  11. package/lib/commands/dataconnect-list.js +64 -0
  12. package/lib/commands/dataconnect-sdk-generate.js +37 -0
  13. package/lib/commands/dataconnect-sql-diff.js +25 -0
  14. package/lib/commands/dataconnect-sql-migrate.js +46 -0
  15. package/lib/commands/deploy.js +27 -1
  16. package/lib/commands/index.js +10 -0
  17. package/lib/commands/init.js +7 -0
  18. package/lib/commands/setup-emulators-dataconnect.js +12 -0
  19. package/lib/config.js +1 -0
  20. package/lib/dataconnect/build.js +23 -0
  21. package/lib/dataconnect/checkIam.js +30 -0
  22. package/lib/dataconnect/client.js +115 -0
  23. package/lib/dataconnect/dataplaneClient.js +16 -0
  24. package/lib/dataconnect/ensureApis.js +12 -0
  25. package/lib/dataconnect/fileUtils.js +89 -0
  26. package/lib/dataconnect/filters.js +45 -0
  27. package/lib/dataconnect/freeTrial.js +23 -0
  28. package/lib/dataconnect/graphqlError.js +13 -0
  29. package/lib/dataconnect/load.js +40 -0
  30. package/lib/dataconnect/names.js +48 -0
  31. package/lib/dataconnect/prompts.js +20 -0
  32. package/lib/dataconnect/provisionCloudSql.js +74 -0
  33. package/lib/dataconnect/schemaMigration.js +171 -0
  34. package/lib/dataconnect/types.js +23 -0
  35. package/lib/deploy/dataconnect/deploy.js +84 -0
  36. package/lib/deploy/dataconnect/index.js +9 -0
  37. package/lib/deploy/dataconnect/prepare.js +30 -0
  38. package/lib/deploy/dataconnect/release.js +65 -0
  39. package/lib/deploy/functions/checkIam.js +4 -34
  40. package/lib/deploy/functions/release/fabricator.js +7 -2
  41. package/lib/deploy/index.js +2 -0
  42. package/lib/downloadUtils.js +2 -2
  43. package/lib/emulator/constants.js +3 -0
  44. package/lib/emulator/controller.js +39 -12
  45. package/lib/emulator/dataconnectEmulator.js +88 -0
  46. package/lib/emulator/download.js +1 -1
  47. package/lib/emulator/downloadableEmulators.js +42 -3
  48. package/lib/emulator/portUtils.js +3 -3
  49. package/lib/emulator/registry.js +6 -1
  50. package/lib/emulator/types.js +3 -0
  51. package/lib/experiments.js +12 -5
  52. package/lib/extensions/emulator/specHelper.js +5 -39
  53. package/lib/frameworks/next/index.js +3 -1
  54. package/lib/frameworks/next/utils.js +1 -1
  55. package/lib/gcp/apphosting.js +6 -1
  56. package/lib/gcp/cloudsql/cloudsqladmin.js +155 -0
  57. package/lib/gcp/cloudsql/connect.js +128 -0
  58. package/lib/gcp/cloudsql/fbToolsAuthClient.js +42 -0
  59. package/lib/gcp/cloudsql/types.js +2 -0
  60. package/lib/gcp/firedata.js +26 -0
  61. package/lib/gcp/iam.js +33 -1
  62. package/lib/gcp/secretManager.js +1 -1
  63. package/lib/hosting/interactive.js +4 -0
  64. package/lib/init/features/dataconnect/index.js +160 -0
  65. package/lib/init/features/emulators.js +13 -0
  66. package/lib/init/features/functions/index.js +15 -3
  67. package/lib/init/features/index.js +3 -1
  68. package/lib/init/index.js +1 -0
  69. package/lib/logger.js +22 -2
  70. package/lib/operation-poller.js +8 -2
  71. package/lib/rc.js +10 -1
  72. package/lib/requireAuth.js +1 -0
  73. package/lib/requireTosAcceptance.js +21 -0
  74. package/lib/utils.js +55 -4
  75. package/package.json +6 -2
  76. package/schema/connector-yaml.json +54 -0
  77. package/schema/dataconnect-yaml.json +72 -0
  78. package/schema/firebase-config.json +103 -0
  79. package/templates/extensions/javascript/package.lint.json +2 -2
  80. package/templates/extensions/javascript/package.nolint.json +2 -2
  81. package/templates/extensions/typescript/package.lint.json +2 -2
  82. package/templates/extensions/typescript/package.nolint.json +2 -2
  83. package/templates/init/dataconnect/connector.yaml +2 -0
  84. package/templates/init/dataconnect/dataconnect.yaml +10 -0
  85. package/templates/init/dataconnect/mutations.gql +4 -0
  86. package/templates/init/dataconnect/queries.gql +6 -0
  87. package/templates/init/dataconnect/schema.gql +15 -0
  88. package/templates/init/functions/javascript/_gitignore +2 -1
  89. package/templates/init/functions/javascript/package.lint.json +2 -2
  90. package/templates/init/functions/javascript/package.nolint.json +2 -2
  91. package/templates/init/functions/python/_gitignore +1 -0
  92. package/templates/init/functions/typescript/_gitignore +1 -0
  93. package/templates/init/functions/typescript/package.lint.json +2 -2
  94. package/templates/init/functions/typescript/package.nolint.json +2 -2
@@ -14,6 +14,7 @@ exports.DEFAULT_PORTS = {
14
14
  auth: 9099,
15
15
  storage: 9199,
16
16
  eventarc: 9299,
17
+ dataconnect: 9399,
17
18
  };
18
19
  exports.FIND_AVAILBLE_PORT_BY_DEFAULT = {
19
20
  ui: true,
@@ -28,6 +29,7 @@ exports.FIND_AVAILBLE_PORT_BY_DEFAULT = {
28
29
  storage: false,
29
30
  extensions: false,
30
31
  eventarc: true,
32
+ dataconnect: true,
31
33
  };
32
34
  exports.EMULATOR_DESCRIPTION = {
33
35
  ui: "Emulator UI",
@@ -42,6 +44,7 @@ exports.EMULATOR_DESCRIPTION = {
42
44
  storage: "Storage Emulator",
43
45
  extensions: "Extensions Emulator",
44
46
  eventarc: "Eventarc Emulator",
47
+ dataconnect: "Data Connect Emulator",
45
48
  };
46
49
  exports.DEFAULT_HOST = "localhost";
47
50
  class Constants {
@@ -12,14 +12,8 @@ const registry_1 = require("./registry");
12
12
  const types_1 = require("./types");
13
13
  const constants_1 = require("./constants");
14
14
  const functionsEmulator_1 = require("./functionsEmulator");
15
- const auth_1 = require("./auth");
16
- const databaseEmulator_1 = require("./databaseEmulator");
17
- const firestoreEmulator_1 = require("./firestoreEmulator");
18
- const hostingEmulator_1 = require("./hostingEmulator");
19
- const eventarcEmulator_1 = require("./eventarcEmulator");
20
15
  const error_1 = require("../error");
21
16
  const projectUtils_1 = require("../projectUtils");
22
- const pubsubEmulator_1 = require("./pubsubEmulator");
23
17
  const commandUtils = require("./commandUtils");
24
18
  const hub_1 = require("./hub");
25
19
  const hubExport_1 = require("./hubExport");
@@ -31,10 +25,9 @@ const hubClient_1 = require("./hubClient");
31
25
  const prompt_1 = require("../prompt");
32
26
  const commandUtils_1 = require("./commandUtils");
33
27
  const fsutils_1 = require("../fsutils");
34
- const storage_1 = require("./storage");
35
28
  const config_1 = require("./storage/rules/config");
36
29
  const getDefaultDatabaseInstance_1 = require("../getDefaultDatabaseInstance");
37
- const auth_2 = require("../auth");
30
+ const auth_1 = require("../auth");
38
31
  const extensionsEmulator_1 = require("./extensionsEmulator");
39
32
  const projectConfig_1 = require("../functions/projectConfig");
40
33
  const downloadableEmulators_1 = require("./downloadableEmulators");
@@ -42,6 +35,15 @@ const frameworks_1 = require("../frameworks");
42
35
  const experiments = require("../experiments");
43
36
  const portUtils_1 = require("./portUtils");
44
37
  const supported_1 = require("../deploy/functions/runtimes/supported");
38
+ const auth_2 = require("./auth");
39
+ const databaseEmulator_1 = require("./databaseEmulator");
40
+ const eventarcEmulator_1 = require("./eventarcEmulator");
41
+ const dataconnectEmulator_1 = require("./dataconnectEmulator");
42
+ const firestoreEmulator_1 = require("./firestoreEmulator");
43
+ const hostingEmulator_1 = require("./hostingEmulator");
44
+ const pubsubEmulator_1 = require("./pubsubEmulator");
45
+ const storage_1 = require("./storage");
46
+ const fileUtils_1 = require("../dataconnect/fileUtils");
45
47
  const START_LOGGING_EMULATOR = utils.envOverride("START_LOGGING_EMULATOR", "false", (val) => val === "true");
46
48
  async function exportOnExit(options) {
47
49
  const exportOnExitDir = options.exportOnExit;
@@ -346,7 +348,7 @@ async function startAll(options, showUI = true, runningTestScript = false) {
346
348
  if (emulatorsNotRunning.length > 0 && !constants_1.Constants.isDemoProject(projectId)) {
347
349
  functionsLogger.logLabeled("WARN", "functions", `The following emulators are not running, calls to these services from the Functions emulator will affect production: ${clc.bold(emulatorsNotRunning.join(", "))}`);
348
350
  }
349
- const account = (0, auth_2.getProjectDefaultAccount)(options.projectRoot);
351
+ const account = (0, auth_1.getProjectDefaultAccount)(options.projectRoot);
350
352
  const functionsEmulator = new functionsEmulator_1.FunctionsEmulator({
351
353
  projectId,
352
354
  projectDir,
@@ -486,13 +488,13 @@ async function startAll(options, showUI = true, runningTestScript = false) {
486
488
  throw new error_1.FirebaseError(`Cannot start the ${constants_1.Constants.description(types_1.Emulators.AUTH)} without a project: run 'firebase init' or provide the --project flag`);
487
489
  }
488
490
  const authAddr = legacyGetFirstAddr(types_1.Emulators.AUTH);
489
- const authEmulator = new auth_1.AuthEmulator({
491
+ const authEmulator = new auth_2.AuthEmulator({
490
492
  host: authAddr.host,
491
493
  port: authAddr.port,
492
494
  projectId,
493
495
  singleProjectMode: singleProjectModeEnabled
494
- ? auth_1.SingleProjectMode.WARNING
495
- : auth_1.SingleProjectMode.NO_WARNING,
496
+ ? auth_2.SingleProjectMode.WARNING
497
+ : auth_2.SingleProjectMode.NO_WARNING,
496
498
  });
497
499
  await startEmulator(authEmulator);
498
500
  if (exportMetadata.auth) {
@@ -515,6 +517,31 @@ async function startAll(options, showUI = true, runningTestScript = false) {
515
517
  });
516
518
  await startEmulator(pubsubEmulator);
517
519
  }
520
+ if (listenForEmulator.dataconnect) {
521
+ const dataConnectAddr = legacyGetFirstAddr(types_1.Emulators.DATACONNECT);
522
+ const config = (0, fileUtils_1.readFirebaseJson)(options.config);
523
+ if (!config.length) {
524
+ throw new error_1.FirebaseError("No Data Connect service found in firebase.json");
525
+ }
526
+ else if (config.length > 1) {
527
+ logger_1.logger.warn(`TODO: Add support for multiple services in the Data Connect emulator. Currently emulating first service ${config[0].source}`);
528
+ }
529
+ let configDir = config[0].source;
530
+ if (!path.isAbsolute(configDir)) {
531
+ const cwd = options.cwd || process.cwd();
532
+ configDir = path.resolve(path.join(cwd), configDir);
533
+ }
534
+ const dataConnectEmulator = new dataconnectEmulator_1.DataConnectEmulator({
535
+ host: dataConnectAddr.host,
536
+ port: dataConnectAddr.port,
537
+ projectId,
538
+ auto_download: true,
539
+ configDir,
540
+ locationId: config[0].location,
541
+ rc: options.rc,
542
+ });
543
+ await startEmulator(dataConnectEmulator);
544
+ }
518
545
  if (listenForEmulator.storage) {
519
546
  const storageAddr = legacyGetFirstAddr(types_1.Emulators.STORAGE);
520
547
  const storageEmulator = new storage_1.StorageEmulator({
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataConnectEmulator = void 0;
4
+ const childProcess = require("child_process");
5
+ const api_1 = require("../api");
6
+ const constants_1 = require("./constants");
7
+ const downloadableEmulators_1 = require("./downloadableEmulators");
8
+ const types_1 = require("./types");
9
+ const error_1 = require("../error");
10
+ const emulatorLogger_1 = require("./emulatorLogger");
11
+ const types_2 = require("../dataconnect/types");
12
+ class DataConnectEmulator {
13
+ constructor(args) {
14
+ this.args = args;
15
+ this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.DATACONNECT);
16
+ }
17
+ async start() {
18
+ const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.DATACONNECT);
19
+ this.logger.log("DEBUG", `Using Postgres connection string: ${this.getLocalConectionString()}`);
20
+ const info = await this.build();
21
+ if ((0, types_2.requiresVector)(info.metadata)) {
22
+ if (constants_1.Constants.isDemoProject(this.args.projectId)) {
23
+ this.logger.logLabeled("WARN", "Data Connect", "Detected a 'demo-' project, but vector embeddings require a real project. Operations that use vector_embed will fail.");
24
+ }
25
+ else {
26
+ this.logger.logLabeled("WARN", "Data Connect", "Operations that use vector_embed will make calls to production Vertex AI");
27
+ }
28
+ }
29
+ return (0, downloadableEmulators_1.start)(types_1.Emulators.DATACONNECT, Object.assign(Object.assign({}, this.args), { http_port: port, grpc_port: port + 1, config_dir: this.args.configDir, local_connection_string: this.getLocalConectionString(), project_id: this.args.projectId, service_location: this.args.locationId }));
30
+ }
31
+ connect() {
32
+ return Promise.resolve();
33
+ }
34
+ stop() {
35
+ return (0, downloadableEmulators_1.stop)(types_1.Emulators.DATACONNECT);
36
+ }
37
+ getInfo() {
38
+ const host = this.args.host || constants_1.Constants.getDefaultHost();
39
+ const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.DATACONNECT);
40
+ return {
41
+ name: this.getName(),
42
+ host,
43
+ port,
44
+ pid: (0, downloadableEmulators_1.getPID)(types_1.Emulators.DATACONNECT),
45
+ timeout: 10000,
46
+ };
47
+ }
48
+ getName() {
49
+ return types_1.Emulators.DATACONNECT;
50
+ }
51
+ async generate(connectorId) {
52
+ const commandInfo = await (0, downloadableEmulators_1.downloadIfNecessary)(types_1.Emulators.DATACONNECT);
53
+ const cmd = [
54
+ "generate",
55
+ `--service_location=${this.args.locationId}`,
56
+ `--config_dir=${this.args.configDir}`,
57
+ `--connector_id=${connectorId}`,
58
+ ];
59
+ const res = childProcess.spawnSync(commandInfo.binary, cmd, { encoding: "utf-8" });
60
+ if (res.error) {
61
+ throw new error_1.FirebaseError(`Error starting up Data Connect emulator: ${res.error}`);
62
+ }
63
+ return res.stdout;
64
+ }
65
+ async build() {
66
+ var _a;
67
+ const commandInfo = await (0, downloadableEmulators_1.downloadIfNecessary)(types_1.Emulators.DATACONNECT);
68
+ const cmd = ["build", `--config_dir=${this.args.configDir}`];
69
+ const res = childProcess.spawnSync(commandInfo.binary, cmd, { encoding: "utf-8" });
70
+ if (res.stderr) {
71
+ throw new error_1.FirebaseError(`Unable to build your Data Connect schema and connectors: ${res.stderr}`);
72
+ }
73
+ try {
74
+ return JSON.parse(res.stdout);
75
+ }
76
+ catch (err) {
77
+ throw new error_1.FirebaseError(`Unable to parse 'fdc build' output: ${(_a = res.stdout) !== null && _a !== void 0 ? _a : res.stderr}`);
78
+ }
79
+ }
80
+ getLocalConectionString() {
81
+ var _a, _b;
82
+ if ((0, api_1.dataConnectLocalConnString)()) {
83
+ return (0, api_1.dataConnectLocalConnString)();
84
+ }
85
+ return (_b = (_a = this.args.rc.getDataconnect()) === null || _a === void 0 ? void 0 : _a.postgres) === null || _b === void 0 ? void 0 : _b.localConnectionString;
86
+ }
87
+ }
88
+ exports.DataConnectEmulator = DataConnectEmulator;
@@ -15,7 +15,7 @@ async function downloadEmulator(name) {
15
15
  const emulator = downloadableEmulators.getDownloadDetails(name);
16
16
  emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("BULLET", name, `downloading ${path.basename(emulator.downloadPath)}...`);
17
17
  fs.ensureDirSync(emulator.opts.cacheDir);
18
- const tmpfile = await downloadUtils.downloadToTmp(emulator.opts.remoteUrl);
18
+ const tmpfile = await downloadUtils.downloadToTmp(emulator.opts.remoteUrl, !!emulator.opts.auth);
19
19
  if (!emulator.opts.skipChecksumAndSize) {
20
20
  await validateSize(tmpfile, emulator.opts.expectedSize);
21
21
  await validateChecksum(tmpfile, emulator.opts.expectedChecksum);
@@ -44,6 +44,17 @@ const EMULATOR_UPDATE_DETAILS = {
44
44
  expectedSize: 65611398,
45
45
  expectedChecksum: "70bb840321423e6ae621a3ae2f314903",
46
46
  },
47
+ dataconnect: process.platform === "darwin"
48
+ ? {
49
+ version: "1.1.15",
50
+ expectedSize: 25600896,
51
+ expectedChecksum: "36dcf9be7273b9ba6052faf0b3c0347f",
52
+ }
53
+ : {
54
+ version: "1.1.15",
55
+ expectedSize: 23036688,
56
+ expectedChecksum: "e42203947bf984993f295976ee3ba2be",
57
+ },
47
58
  };
48
59
  exports.DownloadDetails = {
49
60
  database: {
@@ -107,6 +118,22 @@ exports.DownloadDetails = {
107
118
  namePrefix: "pubsub-emulator",
108
119
  },
109
120
  },
121
+ dataconnect: {
122
+ downloadPath: path.join(CACHE_DIR, `dataconnect-emulator-${EMULATOR_UPDATE_DETAILS.dataconnect.version}`),
123
+ version: EMULATOR_UPDATE_DETAILS.dataconnect.version,
124
+ binaryPath: path.join(CACHE_DIR, `dataconnect-emulator-${EMULATOR_UPDATE_DETAILS.dataconnect.version}`),
125
+ opts: {
126
+ cacheDir: CACHE_DIR,
127
+ remoteUrl: process.platform === "darwin"
128
+ ? `https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-v${EMULATOR_UPDATE_DETAILS.dataconnect.version}`
129
+ : `https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-v${EMULATOR_UPDATE_DETAILS.dataconnect.version}`,
130
+ expectedSize: EMULATOR_UPDATE_DETAILS.dataconnect.expectedSize,
131
+ expectedChecksum: EMULATOR_UPDATE_DETAILS.dataconnect.expectedChecksum,
132
+ skipChecksumAndSize: false,
133
+ namePrefix: "dataconnect-emulator",
134
+ auth: true,
135
+ },
136
+ },
110
137
  };
111
138
  const EmulatorDetails = {
112
139
  database: {
@@ -134,6 +161,11 @@ const EmulatorDetails = {
134
161
  instance: null,
135
162
  stdout: null,
136
163
  },
164
+ dataconnect: {
165
+ name: types_1.Emulators.DATACONNECT,
166
+ instance: null,
167
+ stdout: null,
168
+ },
137
169
  };
138
170
  const Commands = {
139
171
  database: {
@@ -197,6 +229,13 @@ const Commands = {
197
229
  joinArgs: false,
198
230
  shell: false,
199
231
  },
232
+ dataconnect: {
233
+ binary: getExecPath(types_1.Emulators.DATACONNECT),
234
+ args: ["dev"],
235
+ optionalArgs: ["http_port", "grpc_port", "config_dir", "local_connection_string", "project_id"],
236
+ joinArgs: true,
237
+ shell: true,
238
+ },
200
239
  };
201
240
  function getExecPath(name) {
202
241
  const details = getDownloadDetails(name);
@@ -364,10 +403,10 @@ async function stop(targetName) {
364
403
  exports.stop = stop;
365
404
  async function downloadIfNecessary(targetName) {
366
405
  const hasEmulator = fs.existsSync(getExecPath(targetName));
367
- if (hasEmulator) {
368
- return;
406
+ if (!hasEmulator) {
407
+ await (0, download_1.downloadEmulator)(targetName);
369
408
  }
370
- await (0, download_1.downloadEmulator)(targetName);
409
+ return Commands[targetName];
371
410
  }
372
411
  exports.downloadIfNecessary = downloadIfNecessary;
373
412
  async function start(targetName, args, extraEnv = {}) {
@@ -131,9 +131,8 @@ async function checkListenable(arg1, port) {
131
131
  });
132
132
  }
133
133
  exports.checkListenable = checkListenable;
134
- async function waitForPortUsed(port, host) {
135
- const interval = 250;
136
- const timeout = 60000;
134
+ async function waitForPortUsed(port, host, timeout = 60000) {
135
+ const interval = 200;
137
136
  try {
138
137
  await tcpport.waitUntilUsedOnHost(port, host, interval, timeout);
139
138
  }
@@ -147,6 +146,7 @@ const EMULATOR_CAN_LISTEN_ON_PRIMARY_ONLY = {
147
146
  firestore: true,
148
147
  "firestore.websocket": true,
149
148
  pubsub: true,
149
+ dataconnect: true,
150
150
  hub: false,
151
151
  ui: false,
152
152
  auth: true,
@@ -8,6 +8,7 @@ const constants_1 = require("./constants");
8
8
  const emulatorLogger_1 = require("./emulatorLogger");
9
9
  const utils_1 = require("../utils");
10
10
  const apiv2_1 = require("../apiv2");
11
+ const downloadableEmulators_1 = require("./downloadableEmulators");
11
12
  class EmulatorRegistry {
12
13
  static async start(instance) {
13
14
  const description = constants_1.Constants.description(instance.getName());
@@ -18,7 +19,7 @@ class EmulatorRegistry {
18
19
  await instance.start();
19
20
  if (instance.getName() !== types_1.Emulators.EXTENSIONS) {
20
21
  const info = instance.getInfo();
21
- await portUtils.waitForPortUsed(info.port, (0, utils_1.connectableHostname)(info.host));
22
+ await portUtils.waitForPortUsed(info.port, (0, utils_1.connectableHostname)(info.host), info.timeout);
22
23
  }
23
24
  }
24
25
  static async stop(name) {
@@ -47,6 +48,7 @@ class EmulatorRegistry {
47
48
  auth: 3.3,
48
49
  storage: 3.5,
49
50
  eventarc: 3.6,
51
+ dataconnect: 3.7,
50
52
  hub: 4,
51
53
  logging: 5,
52
54
  };
@@ -83,6 +85,9 @@ class EmulatorRegistry {
83
85
  }
84
86
  return Object.assign(Object.assign({}, info), { host: (0, utils_1.connectableHostname)(info.host) });
85
87
  }
88
+ static getDetails(emulator) {
89
+ return (0, downloadableEmulators_1.get)(emulator);
90
+ }
86
91
  static url(emulator, req) {
87
92
  const url = new URL("http://unknown/");
88
93
  if (req) {
@@ -15,6 +15,7 @@ var Emulators;
15
15
  Emulators["STORAGE"] = "storage";
16
16
  Emulators["EXTENSIONS"] = "extensions";
17
17
  Emulators["EVENTARC"] = "eventarc";
18
+ Emulators["DATACONNECT"] = "dataconnect";
18
19
  })(Emulators = exports.Emulators || (exports.Emulators = {}));
19
20
  exports.DOWNLOADABLE_EMULATORS = [
20
21
  Emulators.FIRESTORE,
@@ -22,6 +23,7 @@ exports.DOWNLOADABLE_EMULATORS = [
22
23
  Emulators.PUBSUB,
23
24
  Emulators.UI,
24
25
  Emulators.STORAGE,
26
+ Emulators.DATACONNECT,
25
27
  ];
26
28
  exports.IMPORT_EXPORT_EMULATORS = [
27
29
  Emulators.FIRESTORE,
@@ -38,6 +40,7 @@ exports.ALL_SERVICE_EMULATORS = [
38
40
  Emulators.PUBSUB,
39
41
  Emulators.STORAGE,
40
42
  Emulators.EVENTARC,
43
+ Emulators.DATACONNECT,
41
44
  ].filter((v) => v);
42
45
  exports.EMULATORS_SUPPORTED_BY_FUNCTIONS = [
43
46
  Emulators.FIRESTORE,
@@ -20,11 +20,13 @@ exports.ALL_EXPERIMENTS = experiments({
20
20
  rtdbmanagement: {
21
21
  shortDescription: "Use new endpoint to administer realtime database instances",
22
22
  },
23
- pythonfunctions: {
24
- shortDescription: "Python support for Cloud Functions for Firebase",
25
- fullDescription: "Adds the ability to initializea and deploy Cloud " +
26
- "Functions for Firebase in Python. While this feature is experimental " +
27
- "breaking API changes are allowed in MINOR API revisions",
23
+ functionsv2deployoptimizations: {
24
+ shortDescription: "Optimize deployments of v2 firebase functions",
25
+ fullDescription: "Reuse build images across funtions to increase performance and reliaibility " +
26
+ "of deploys. This has been made an experiment due to backend bugs that are " +
27
+ "temporarily causing failures in some regions with this optimization enabled",
28
+ public: true,
29
+ default: false,
28
30
  },
29
31
  deletegcfartifacts: {
30
32
  shortDescription: `Add the ${(0, colorette_1.bold)("functions:deletegcfartifacts")} command to purge docker build images`,
@@ -89,6 +91,11 @@ exports.ALL_EXPERIMENTS = experiments({
89
91
  default: false,
90
92
  public: false,
91
93
  },
94
+ dataconnect: {
95
+ shortDescription: "Enable Data Connect related features.",
96
+ fullDescription: "Enable Data Connect related features.",
97
+ public: false,
98
+ },
92
99
  });
93
100
  function isValidExperiment(name) {
94
101
  return Object.keys(exports.ALL_EXPERIMENTS).includes(name);
@@ -1,13 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntime = exports.DEFAULT_RUNTIME = exports.getFunctionProperties = exports.getFunctionResourcesWithParamSubstitution = exports.readFileFromDirectory = exports.readPostinstall = exports.readExtensionYaml = void 0;
4
- const yaml = require("yaml");
5
- const path = require("path");
6
- const fs = require("fs-extra");
3
+ exports.getRuntime = exports.DEFAULT_RUNTIME = exports.getFunctionProperties = exports.getFunctionResourcesWithParamSubstitution = exports.readPostinstall = exports.readExtensionYaml = void 0;
7
4
  const supported = require("../../deploy/functions/runtimes/supported");
8
5
  const error_1 = require("../../error");
9
6
  const extensionsHelper_1 = require("../extensionsHelper");
10
7
  const utils_1 = require("../utils");
8
+ const utils_2 = require("../../utils");
11
9
  const SPEC_FILE = "extension.yaml";
12
10
  const POSTINSTALL_FILE = "POSTINSTALL.md";
13
11
  const validFunctionTypes = [
@@ -15,22 +13,11 @@ const validFunctionTypes = [
15
13
  "firebaseextensions.v1beta.v2function",
16
14
  "firebaseextensions.v1beta.scheduledFunction",
17
15
  ];
18
- function wrappedSafeLoad(source) {
19
- try {
20
- return yaml.parse(source);
21
- }
22
- catch (err) {
23
- if (err instanceof yaml.YAMLParseError) {
24
- throw new error_1.FirebaseError(`YAML Error: ${err.message}`, { original: err });
25
- }
26
- throw err;
27
- }
28
- }
29
16
  async function readExtensionYaml(directory) {
30
17
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
31
- const extensionYaml = await readFileFromDirectory(directory, SPEC_FILE);
18
+ const extensionYaml = await (0, utils_2.readFileFromDirectory)(directory, SPEC_FILE);
32
19
  const source = extensionYaml.source;
33
- const spec = wrappedSafeLoad(source);
20
+ const spec = (0, utils_2.wrappedSafeLoad)(source);
34
21
  spec.params = (_a = spec.params) !== null && _a !== void 0 ? _a : [];
35
22
  spec.systemParams = (_b = spec.systemParams) !== null && _b !== void 0 ? _b : [];
36
23
  spec.resources = (_c = spec.resources) !== null && _c !== void 0 ? _c : [];
@@ -44,31 +31,10 @@ async function readExtensionYaml(directory) {
44
31
  }
45
32
  exports.readExtensionYaml = readExtensionYaml;
46
33
  async function readPostinstall(directory) {
47
- const content = await readFileFromDirectory(directory, POSTINSTALL_FILE);
34
+ const content = await (0, utils_2.readFileFromDirectory)(directory, POSTINSTALL_FILE);
48
35
  return content.source;
49
36
  }
50
37
  exports.readPostinstall = readPostinstall;
51
- function readFileFromDirectory(directory, file) {
52
- return new Promise((resolve, reject) => {
53
- fs.readFile(path.resolve(directory, file), "utf8", (err, data) => {
54
- if (err) {
55
- if (err.code === "ENOENT") {
56
- return reject(new error_1.FirebaseError(`Could not find "${file}" in "${directory}"`, { original: err }));
57
- }
58
- reject(new error_1.FirebaseError(`Failed to read file "${file}" in "${directory}"`, { original: err }));
59
- }
60
- else {
61
- resolve(data);
62
- }
63
- });
64
- }).then((source) => {
65
- return {
66
- source,
67
- sourceDirectory: directory,
68
- };
69
- });
70
- }
71
- exports.readFileFromDirectory = readFileFromDirectory;
72
38
  function getFunctionResourcesWithParamSubstitution(extensionSpec, params) {
73
39
  const rawResources = extensionSpec.resources.filter((resource) => validFunctionTypes.includes(resource.type));
74
40
  return (0, extensionsHelper_1.substituteParams)(rawResources, params);
@@ -400,7 +400,9 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context)
400
400
  (0, utils_2.getProductionDistDirFiles)(sourceDir, distDir),
401
401
  (0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir)),
402
402
  ]);
403
- await Promise.all(productionDistDirfiles.map((file) => (0, fs_extra_1.copy)(file, file.replace(sourceDir, destDir), { recursive: true })));
403
+ await Promise.all(productionDistDirfiles.map((file) => (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir, file), (0, path_1.join)(destDir, distDir, file), {
404
+ recursive: true,
405
+ })));
404
406
  return { packageJson, frameworksEntry: "next.js", dotEnv };
405
407
  }
406
408
  exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
@@ -230,7 +230,7 @@ async function getProductionDistDirFiles(sourceDir, distDir) {
230
230
  ignore: [(0, path_1.join)("cache", "webpack", "*-development", "**"), (0, path_1.join)("cache", "eslint", "**")],
231
231
  cwd: (0, path_1.join)(sourceDir, distDir),
232
232
  nodir: true,
233
- absolute: true,
233
+ absolute: false,
234
234
  realpath: utils_2.IS_WINDOWS,
235
235
  }, (err, matches) => {
236
236
  if (err)
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.serviceAgentEmail = exports.client = exports.API_VERSION = void 0;
3
+ exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.parseBackendName = exports.serviceAgentEmail = exports.client = exports.API_VERSION = void 0;
4
4
  const proto = require("../gcp/proto");
5
5
  const apiv2_1 = require("../apiv2");
6
6
  const projectUtils_1 = require("../projectUtils");
@@ -24,6 +24,11 @@ function serviceAgentEmail(projectNumber) {
24
24
  return `service-${projectNumber}@${P4SA_DOMAIN}`;
25
25
  }
26
26
  exports.serviceAgentEmail = serviceAgentEmail;
27
+ function parseBackendName(backendName) {
28
+ const [, projectName, , location, , id] = backendName.split("/");
29
+ return { projectName, location, id };
30
+ }
31
+ exports.parseBackendName = parseBackendName;
27
32
  async function createBackend(projectId, location, backendReqBoby, backendId) {
28
33
  const res = await exports.client.post(`projects/${projectId}/locations/${location}/backends`, Object.assign(Object.assign({}, backendReqBoby), { labels: Object.assign(Object.assign({}, backendReqBoby.labels), deploymentTool.labels()) }), { queryParams: { backendId } });
29
34
  return res.body;