firebase-tools 13.19.0 → 13.20.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 (57) hide show
  1. package/lib/apiv2.js +8 -1
  2. package/lib/auth.js +14 -2
  3. package/lib/commands/dataconnect-sdk-generate.js +5 -2
  4. package/lib/commands/emulators-start.js +3 -0
  5. package/lib/commands/init.js +20 -16
  6. package/lib/commands/setup-emulators-dataconnect.js +0 -14
  7. package/lib/dataconnect/dataplaneClient.js +12 -9
  8. package/lib/dataconnect/fileUtils.js +16 -4
  9. package/lib/dataconnect/freeTrial.js +8 -6
  10. package/lib/dataconnect/provisionCloudSql.js +4 -4
  11. package/lib/dataconnect/types.js +1 -0
  12. package/lib/dataconnect/webhook.js +31 -0
  13. package/lib/deploy/dataconnect/deploy.js +2 -0
  14. package/lib/deploy/dataconnect/prepare.js +2 -0
  15. package/lib/deploy/dataconnect/release.js +10 -5
  16. package/lib/deploy/functions/runtimes/node/index.js +6 -1
  17. package/lib/emulator/commandUtils.js +6 -1
  18. package/lib/emulator/constants.js +1 -1
  19. package/lib/emulator/controller.js +17 -3
  20. package/lib/emulator/dataconnect/pg-gateway/auth/base-auth-flow.js +11 -0
  21. package/lib/emulator/dataconnect/pg-gateway/auth/cert.js +69 -0
  22. package/lib/emulator/dataconnect/pg-gateway/auth/index.js +22 -0
  23. package/lib/emulator/dataconnect/pg-gateway/auth/md5.js +135 -0
  24. package/lib/emulator/dataconnect/pg-gateway/auth/password.js +65 -0
  25. package/lib/emulator/dataconnect/pg-gateway/auth/sasl/sasl-mechanism.js +34 -0
  26. package/lib/emulator/dataconnect/pg-gateway/auth/sasl/scram-sha-256.js +298 -0
  27. package/lib/emulator/dataconnect/pg-gateway/auth/trust.js +2 -0
  28. package/lib/emulator/dataconnect/pg-gateway/backend-error.js +75 -0
  29. package/lib/emulator/dataconnect/pg-gateway/buffer-reader.js +55 -0
  30. package/lib/emulator/dataconnect/pg-gateway/buffer-writer.js +79 -0
  31. package/lib/emulator/dataconnect/pg-gateway/connection.js +419 -0
  32. package/lib/emulator/dataconnect/pg-gateway/connection.types.js +8 -0
  33. package/lib/emulator/dataconnect/pg-gateway/crypto.js +40 -0
  34. package/lib/emulator/dataconnect/pg-gateway/duplex.js +53 -0
  35. package/lib/emulator/dataconnect/pg-gateway/index.js +27 -0
  36. package/lib/emulator/dataconnect/pg-gateway/message-buffer.js +96 -0
  37. package/lib/emulator/dataconnect/pg-gateway/message-codes.js +54 -0
  38. package/lib/emulator/dataconnect/pg-gateway/platforms/node/index.js +13 -0
  39. package/lib/emulator/dataconnect/pg-gateway/polyfills/readable-stream-async-iterator.js +36 -0
  40. package/lib/emulator/dataconnect/pg-gateway/utils.js +40 -0
  41. package/lib/emulator/dataconnect/pgliteServer.js +134 -0
  42. package/lib/emulator/dataconnectEmulator.js +55 -73
  43. package/lib/emulator/dataconnectToolkitController.js +44 -0
  44. package/lib/emulator/downloadableEmulators.js +22 -11
  45. package/lib/emulator/hub.js +2 -1
  46. package/lib/emulator/portUtils.js +9 -11
  47. package/lib/emulator/storage/rules/runtime.js +1 -1
  48. package/lib/experiments.js +1 -0
  49. package/lib/init/features/dataconnect/index.js +148 -111
  50. package/lib/init/features/dataconnect/sdk.js +40 -27
  51. package/lib/init/features/emulators.js +2 -14
  52. package/lib/prompt.js +1 -1
  53. package/lib/rc.js +1 -9
  54. package/package.json +3 -1
  55. package/schema/connector-yaml.json +14 -0
  56. package/schema/firebase-config.json +6 -0
  57. package/templates/init/dataconnect/queries.gql +1 -2
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.actuate = exports.doSetup = void 0;
3
+ exports.actuate = exports.doSetup = exports.FDC_APP_FOLDER = void 0;
4
4
  const yaml = require("yaml");
5
5
  const fs = require("fs");
6
6
  const clc = require("colorette");
@@ -13,13 +13,15 @@ const dataconnectEmulator_1 = require("../../../emulator/dataconnectEmulator");
13
13
  const error_1 = require("../../../error");
14
14
  const lodash_1 = require("lodash");
15
15
  const utils_1 = require("../../../utils");
16
+ exports.FDC_APP_FOLDER = "_FDC_APP_FOLDER";
16
17
  async function doSetup(setup, config) {
17
18
  const sdkInfo = await askQuestions(setup, config);
18
19
  await actuate(sdkInfo, setup.projectId);
20
+ (0, utils_1.logSuccess)(`If you'd like to generate additional SDKs later, run ${clc.bold("firebase init dataconnect:sdk")}`);
19
21
  }
20
22
  exports.doSetup = doSetup;
21
23
  async function askQuestions(setup, config) {
22
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
23
25
  const serviceCfgs = (0, fileUtils_1.readFirebaseJson)(config);
24
26
  const serviceInfos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(setup.projectId || "", config, c.source)));
25
27
  const connectorChoices = serviceInfos
@@ -33,27 +35,22 @@ async function askQuestions(setup, config) {
33
35
  })
34
36
  .flat();
35
37
  if (!connectorChoices.length) {
36
- throw new error_1.FirebaseError(`Your config has no connectors to set up SDKs for. Run ${clc.bold("firebase init dataconnect")} to set up a service and conenctors.`);
38
+ throw new error_1.FirebaseError(`Your config has no connectors to set up SDKs for. Run ${clc.bold("firebase init dataconnect")} to set up a service and connectors.`);
37
39
  }
38
- const connectorInfo = await (0, prompt_1.promptOnce)({
39
- message: "Which connector do you want set up a generated SDK for?",
40
- type: "list",
41
- choices: connectorChoices,
42
- });
43
40
  let targetPlatform = types_1.Platform.UNDETERMINED;
44
- let appDir;
45
- const cwdPlatformGuess = await (0, fileUtils_1.getPlatformFromFolder)(process.cwd());
41
+ let appDir = process.env[exports.FDC_APP_FOLDER] || process.cwd();
42
+ const cwdPlatformGuess = await (0, fileUtils_1.getPlatformFromFolder)(appDir);
46
43
  if (cwdPlatformGuess !== types_1.Platform.UNDETERMINED) {
47
- (0, utils_1.logSuccess)(`Detected ${cwdPlatformGuess} app in current directory ${process.cwd()}`);
44
+ (0, utils_1.logSuccess)(`Detected ${cwdPlatformGuess} app in directory ${appDir}`);
48
45
  targetPlatform = cwdPlatformGuess;
49
- appDir = process.cwd();
50
46
  }
51
47
  else {
52
48
  (0, utils_1.logBullet)(`Couldn't automatically detect your app directory.`);
53
- appDir = await (0, prompt_1.promptForDirectory)({
54
- config,
55
- message: "Where is your app directory?",
56
- });
49
+ appDir =
50
+ (_a = process.env[exports.FDC_APP_FOLDER]) !== null && _a !== void 0 ? _a : (await (0, prompt_1.promptForDirectory)({
51
+ config,
52
+ message: "Where is your app directory? Leave blank to set up a generated SDK in your current directory.",
53
+ }));
57
54
  const platformGuess = await (0, fileUtils_1.getPlatformFromFolder)(appDir);
58
55
  if (platformGuess !== types_1.Platform.UNDETERMINED) {
59
56
  (0, utils_1.logSuccess)(`Detected ${platformGuess} app in directory ${appDir}`);
@@ -61,34 +58,40 @@ async function askQuestions(setup, config) {
61
58
  }
62
59
  else {
63
60
  (0, utils_1.logBullet)("Couldn't automatically detect your app's platform.");
61
+ const platforms = [
62
+ { name: "iOS (Swift)", value: types_1.Platform.IOS },
63
+ { name: "Web (JavaScript)", value: types_1.Platform.WEB },
64
+ { name: "Android (Kotlin)", value: types_1.Platform.ANDROID },
65
+ ];
64
66
  targetPlatform = await (0, prompt_1.promptOnce)({
65
67
  message: "Which platform do you want to set up a generated SDK for?",
66
68
  type: "list",
67
- choices: [
68
- { name: "iOS (Swift)", value: types_1.Platform.IOS },
69
- { name: "Web (JavaScript)", value: types_1.Platform.WEB },
70
- { name: "Android (Kotlin)", value: types_1.Platform.ANDROID },
71
- ],
69
+ choices: platforms,
72
70
  });
73
71
  }
74
72
  }
73
+ const connectorInfo = await (0, prompt_1.promptOnce)({
74
+ message: "Which connector do you want set up a generated SDK for?",
75
+ type: "list",
76
+ choices: connectorChoices,
77
+ });
75
78
  const newConnectorYaml = JSON.parse(JSON.stringify(connectorInfo.connectorYaml));
76
79
  if (!newConnectorYaml.generate) {
77
80
  newConnectorYaml.generate = {};
78
81
  }
79
82
  let displayIOSWarning = false;
80
83
  if (targetPlatform === types_1.Platform.IOS) {
81
- const outputDir = ((_a = newConnectorYaml.generate.swiftSdk) === null || _a === void 0 ? void 0 : _a.outputDir) ||
84
+ const outputDir = ((_b = newConnectorYaml.generate.swiftSdk) === null || _b === void 0 ? void 0 : _b.outputDir) ||
82
85
  path.relative(connectorInfo.directory, path.join(appDir, `generated/swift`));
83
- const pkg = (_c = (_b = newConnectorYaml.generate.swiftSdk) === null || _b === void 0 ? void 0 : _b.package) !== null && _c !== void 0 ? _c : (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(newConnectorYaml.connectorId));
86
+ const pkg = (_d = (_c = newConnectorYaml.generate.swiftSdk) === null || _c === void 0 ? void 0 : _c.package) !== null && _d !== void 0 ? _d : (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(newConnectorYaml.connectorId));
84
87
  const swiftSdk = { outputDir, package: pkg };
85
88
  newConnectorYaml.generate.swiftSdk = swiftSdk;
86
89
  displayIOSWarning = true;
87
90
  }
88
91
  if (targetPlatform === types_1.Platform.WEB) {
89
- const outputDir = ((_d = newConnectorYaml.generate.javascriptSdk) === null || _d === void 0 ? void 0 : _d.outputDir) ||
92
+ const outputDir = ((_e = newConnectorYaml.generate.javascriptSdk) === null || _e === void 0 ? void 0 : _e.outputDir) ||
90
93
  path.relative(connectorInfo.directory, path.join(appDir, `generated/javascript/${newConnectorYaml.connectorId}`));
91
- const pkg = (_f = (_e = newConnectorYaml.generate.javascriptSdk) === null || _e === void 0 ? void 0 : _e.package) !== null && _f !== void 0 ? _f : `@firebasegen/${connectorInfo.connectorYaml.connectorId}`;
94
+ const pkg = (_g = (_f = newConnectorYaml.generate.javascriptSdk) === null || _f === void 0 ? void 0 : _f.package) !== null && _g !== void 0 ? _g : `@firebasegen/${connectorInfo.connectorYaml.connectorId}`;
92
95
  const javascriptSdk = {
93
96
  outputDir,
94
97
  package: pkg,
@@ -101,6 +104,16 @@ async function askQuestions(setup, config) {
101
104
  }
102
105
  newConnectorYaml.generate.javascriptSdk = javascriptSdk;
103
106
  }
107
+ if (targetPlatform === types_1.Platform.DART) {
108
+ const outputDir = ((_h = newConnectorYaml.generate.dartSdk) === null || _h === void 0 ? void 0 : _h.outputDir) ||
109
+ path.relative(connectorInfo.directory, path.join(appDir, `generated/dart/${newConnectorYaml.connectorId}`));
110
+ const pkg = (_k = (_j = newConnectorYaml.generate.dartSdk) === null || _j === void 0 ? void 0 : _j.package) !== null && _k !== void 0 ? _k : newConnectorYaml.connectorId;
111
+ const dartSdk = {
112
+ outputDir,
113
+ package: pkg,
114
+ };
115
+ newConnectorYaml.generate.dartSdk = dartSdk;
116
+ }
104
117
  if (targetPlatform === types_1.Platform.ANDROID) {
105
118
  let baseDir = path.join(appDir, `generated/kotlin`);
106
119
  for (const candidateSubdir of ["app/src/main/java", "app/src/main/kotlin"]) {
@@ -109,9 +122,9 @@ async function askQuestions(setup, config) {
109
122
  baseDir = candidateDir;
110
123
  }
111
124
  }
112
- const outputDir = ((_g = newConnectorYaml.generate.kotlinSdk) === null || _g === void 0 ? void 0 : _g.outputDir) ||
125
+ const outputDir = ((_l = newConnectorYaml.generate.kotlinSdk) === null || _l === void 0 ? void 0 : _l.outputDir) ||
113
126
  path.relative(connectorInfo.directory, baseDir);
114
- const pkg = (_j = (_h = newConnectorYaml.generate.kotlinSdk) === null || _h === void 0 ? void 0 : _h.package) !== null && _j !== void 0 ? _j : `connectors.${(0, lodash_1.snakeCase)(connectorInfo.connectorYaml.connectorId)}`;
127
+ const pkg = (_o = (_m = newConnectorYaml.generate.kotlinSdk) === null || _m === void 0 ? void 0 : _m.package) !== null && _o !== void 0 ? _o : `connectors.${(0, lodash_1.snakeCase)(connectorInfo.connectorYaml.connectorId)}`;
115
128
  const kotlinSdk = {
116
129
  outputDir,
117
130
  package: pkg,
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.doSetup = exports.DEFAULT_POSTGRES_CONNECTION = void 0;
3
+ exports.doSetup = void 0;
4
4
  const clc = require("colorette");
5
- const _ = require("lodash");
6
5
  const utils = require("../../utils");
7
6
  const prompt_1 = require("../../prompt");
8
7
  const types_1 = require("../../emulator/types");
9
8
  const constants_1 = require("../../emulator/constants");
10
9
  const downloadableEmulators_1 = require("../../emulator/downloadableEmulators");
11
- exports.DEFAULT_POSTGRES_CONNECTION = "postgresql://localhost:5432?sslmode=disable";
12
10
  async function doSetup(setup, config) {
13
11
  var _a, _b, _c;
14
12
  const choices = types_1.ALL_SERVICE_EMULATORS.map((e) => {
@@ -78,16 +76,6 @@ async function doSetup(setup, config) {
78
76
  ui.port = isNaN(portNum) ? undefined : portNum;
79
77
  }
80
78
  }
81
- if (selections.emulators.includes(types_1.Emulators.DATACONNECT)) {
82
- const defaultConnectionString = (_c = (_b = (_a = setup.rcfile.dataconnectEmulatorConfig) === null || _a === void 0 ? void 0 : _a.postgres) === null || _b === void 0 ? void 0 : _b.localConnectionString) !== null && _c !== void 0 ? _c : exports.DEFAULT_POSTGRES_CONNECTION;
83
- const localConnectionString = await (0, prompt_1.promptOnce)({
84
- type: "input",
85
- name: "localConnectionString",
86
- message: `What is the connection string of the local Postgres instance you would like to use with the Data Connect emulator?`,
87
- default: defaultConnectionString,
88
- });
89
- setup.rcfile.dataconnectEmulatorConfig = { postgres: { localConnectionString } };
90
- }
91
79
  await (0, prompt_1.prompt)(selections, [
92
80
  {
93
81
  name: "download",
@@ -106,7 +94,7 @@ async function doSetup(setup, config) {
106
94
  await (0, downloadableEmulators_1.downloadIfNecessary)(selected);
107
95
  }
108
96
  }
109
- if (_.get(setup, "config.emulators.ui.enabled")) {
97
+ if ((_c = (_b = (_a = setup === null || setup === void 0 ? void 0 : setup.config) === null || _a === void 0 ? void 0 : _a.emulators) === null || _b === void 0 ? void 0 : _b.ui) === null || _c === void 0 ? void 0 : _c.enabled) {
110
98
  (0, downloadableEmulators_1.downloadIfNecessary)(types_1.Emulators.UI);
111
99
  }
112
100
  }
package/lib/prompt.js CHANGED
@@ -55,7 +55,7 @@ async function promptForDirectory(args) {
55
55
  let dir = "";
56
56
  while (!dir) {
57
57
  const target = args.config.path(await promptOnce({
58
- message: "Where is your app directory?",
58
+ message: args.message,
59
59
  }));
60
60
  if ((0, fsutils_1.fileExistsSync)(target)) {
61
61
  logger_1.logger.error(`Expected a directory, but ${target} is a file. Please provide a path to a directory.`);
package/lib/rc.js CHANGED
@@ -37,7 +37,7 @@ class RC {
37
37
  }
38
38
  constructor(rcpath, data) {
39
39
  this.path = rcpath;
40
- this.data = Object.assign({ projects: {}, targets: {}, etags: {}, dataconnectEmulatorConfig: {} }, data);
40
+ this.data = Object.assign({ projects: {}, targets: {}, etags: {} }, data);
41
41
  }
42
42
  set(key, value) {
43
43
  _.set(this.data, key, value);
@@ -152,14 +152,6 @@ class RC {
152
152
  this.data.etags[projectId][resourceType] = etagData;
153
153
  this.save();
154
154
  }
155
- getDataconnect() {
156
- var _a;
157
- return (_a = this.data.dataconnectEmulatorConfig) !== null && _a !== void 0 ? _a : {};
158
- }
159
- setDataconnect(localConnectionString) {
160
- this.data.dataconnectEmulatorConfig = { postgres: { localConnectionString } };
161
- this.save();
162
- }
163
155
  save() {
164
156
  if (this.path) {
165
157
  fs.writeFileSync(this.path, JSON.stringify(this.data, null, 2), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "13.19.0",
3
+ "version": "13.20.1",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -60,6 +60,7 @@
60
60
  ]
61
61
  },
62
62
  "dependencies": {
63
+ "@electric-sql/pglite": "^0.2.0",
63
64
  "@google-cloud/cloud-sql-connector": "^1.3.3",
64
65
  "@google-cloud/pubsub": "^4.5.0",
65
66
  "abort-controller": "^3.0.0",
@@ -94,6 +95,7 @@
94
95
  "leven": "^3.1.0",
95
96
  "libsodium-wrappers": "^0.7.10",
96
97
  "lodash": "^4.17.21",
98
+ "lsofi": "1.0.0",
97
99
  "marked": "^13.0.2",
98
100
  "marked-terminal": "^7.0.0",
99
101
  "mime": "^2.5.2",
@@ -20,6 +20,20 @@
20
20
  }
21
21
  }
22
22
  },
23
+ "dartSdk": {
24
+ "additionalProperties": true,
25
+ "type": "object",
26
+ "properties": {
27
+ "outputDir": {
28
+ "type": "string",
29
+ "description": "Path to the directory where generated files should be written to."
30
+ },
31
+ "package": {
32
+ "type": "string",
33
+ "description": "The package name to use for the generated code."
34
+ }
35
+ }
36
+ },
23
37
  "kotlinSdk": {
24
38
  "additionalProperties": true,
25
39
  "type": "object",
@@ -401,6 +401,12 @@
401
401
  },
402
402
  "port": {
403
403
  "type": "number"
404
+ },
405
+ "postgresHost": {
406
+ "type": "string"
407
+ },
408
+ "postgresPort": {
409
+ "type": "number"
404
410
  }
405
411
  },
406
412
  "type": "object"
@@ -44,8 +44,7 @@
44
44
  # title
45
45
  # imageUrl
46
46
  # genre
47
- # metadata: movieMetadatas_on_movie {
48
- # director
47
+ # metadata: movieMetadata_on_movie {
49
48
  # rating
50
49
  # releaseYear
51
50
  # description