firebase-tools 15.5.0 → 15.6.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 (61) hide show
  1. package/lib/apiv2.js +11 -5
  2. package/lib/apphosting/backend.js +1 -1
  3. package/lib/commands/deploy.js +3 -0
  4. package/lib/commands/init.js +5 -0
  5. package/lib/config.js +1 -0
  6. package/lib/dataconnect/client.js +2 -2
  7. package/lib/dataconnect/prompts.js +14 -0
  8. package/lib/deploy/auth/deploy.js +63 -0
  9. package/lib/deploy/auth/index.js +9 -0
  10. package/lib/deploy/auth/prepare.js +26 -0
  11. package/lib/deploy/auth/release.js +5 -0
  12. package/lib/deploy/dataconnect/release.js +11 -0
  13. package/lib/deploy/functions/backend.js +10 -0
  14. package/lib/deploy/functions/build.js +2 -2
  15. package/lib/deploy/functions/checkIam.js +3 -2
  16. package/lib/deploy/functions/deploy.js +4 -2
  17. package/lib/deploy/functions/prepare.js +5 -2
  18. package/lib/deploy/functions/prepareFunctionsUpload.js +7 -5
  19. package/lib/deploy/functions/release/fabricator.js +96 -15
  20. package/lib/deploy/functions/release/index.js +2 -1
  21. package/lib/deploy/functions/runtimes/dart.js +42 -0
  22. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +4 -1
  23. package/lib/deploy/functions/runtimes/index.js +9 -1
  24. package/lib/deploy/functions/runtimes/supported/types.js +6 -0
  25. package/lib/deploy/index.js +2 -0
  26. package/lib/emulator/auth/index.js +23 -17
  27. package/lib/emulator/auth/operations.js +9 -1
  28. package/lib/emulator/downloadableEmulatorInfo.json +31 -31
  29. package/lib/emulator/hubExport.js +15 -1
  30. package/lib/ensureApiEnabled.js +2 -2
  31. package/lib/gcp/cloudbilling.js +6 -3
  32. package/lib/gcp/iam.js +1 -1
  33. package/lib/gcp/runv2.js +75 -3
  34. package/lib/gcp/serviceusage.js +2 -2
  35. package/lib/gemini/fdcExperience.js +0 -11
  36. package/lib/init/features/auth.js +72 -0
  37. package/lib/init/features/dataconnect/resolver.js +17 -3
  38. package/lib/init/features/functions/index.js +22 -14
  39. package/lib/init/features/functions/javascript.js +18 -3
  40. package/lib/init/features/functions/typescript.js +20 -3
  41. package/lib/init/features/functions/utils.js +10 -0
  42. package/lib/init/features/genkit/index.js +3 -2
  43. package/lib/init/features/index.js +6 -2
  44. package/lib/init/index.js +11 -1
  45. package/lib/management/provisioning/provision.js +3 -0
  46. package/lib/management/provisioning/types.js +7 -0
  47. package/lib/mcp/resources/guides/init_auth.js +19 -2
  48. package/lib/mcp/tools/apptesting/tests.js +6 -4
  49. package/lib/mcp/tools/core/init.js +31 -0
  50. package/lib/tsconfig.publish.tsbuildinfo +1 -1
  51. package/package.json +1 -1
  52. package/schema/firebase-config.json +41 -0
  53. package/templates/init/apptesting/smoke_test.yaml +1 -1
  54. package/templates/init/dataconnect/secondary_schema.gql +8 -0
  55. package/templates/init/functions/javascript/index-ongraphrequest.js +36 -0
  56. package/templates/init/functions/javascript/package-ongraphrequest.lint.json +28 -0
  57. package/templates/init/functions/javascript/package-ongraphrequest.nolint.json +25 -0
  58. package/templates/init/functions/typescript/index-ongraphrequest.ts +44 -0
  59. package/templates/init/functions/typescript/package-ongraphrequest.lint.json +33 -0
  60. package/templates/init/functions/typescript/package-ongraphrequest.nolint.json +27 -0
  61. package/lib/mcp/util.test.js +0 -468
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.doSetup = doSetup;
3
+ exports.askQuestions = askQuestions;
4
+ exports.actuate = actuate;
4
5
  const clc = require("colorette");
5
6
  const logger_1 = require("../../../logger");
6
7
  const prompt_1 = require("../../../prompt");
@@ -11,7 +12,7 @@ const error_1 = require("../../../error");
11
12
  const api_1 = require("../../../api");
12
13
  const supported = require("../../../deploy/functions/runtimes/supported");
13
14
  const MAX_ATTEMPTS = 5;
14
- async function doSetup(setup, config, options) {
15
+ async function askQuestions(setup, config, options) {
15
16
  const projectId = setup?.rcfile?.projects?.default;
16
17
  if (projectId) {
17
18
  await (0, requirePermissions_1.requirePermissions)({ ...options, project: projectId });
@@ -23,7 +24,7 @@ async function doSetup(setup, config, options) {
23
24
  setup.functions = {};
24
25
  if (!config.src.functions) {
25
26
  setup.config.functions = [];
26
- return initNewCodebase(setup, config);
27
+ return initNewCodebase(setup);
27
28
  }
28
29
  setup.config.functions = (0, projectConfig_1.normalizeAndValidate)(setup.config.functions);
29
30
  const codebases = setup.config.functions.map((cfg) => clc.bold(cfg.codebase));
@@ -43,9 +44,9 @@ async function doSetup(setup, config, options) {
43
44
  default: "new",
44
45
  choices,
45
46
  });
46
- return initOpt === "new" ? initNewCodebase(setup, config) : overwriteCodebase(setup, config);
47
+ return initOpt === "new" ? initNewCodebase(setup) : overwriteCodebase(setup);
47
48
  }
48
- async function initNewCodebase(setup, config) {
49
+ async function initNewCodebase(setup) {
49
50
  logger_1.logger.info("Let's create a new codebase for your functions.");
50
51
  logger_1.logger.info("A directory corresponding to the codebase will be created in your project");
51
52
  logger_1.logger.info("with sample code pre-configured.\n");
@@ -100,9 +101,9 @@ async function initNewCodebase(setup, config) {
100
101
  });
101
102
  setup.functions.source = source;
102
103
  setup.functions.codebase = codebase;
103
- return languageSetup(setup, config);
104
+ return languageSetup(setup);
104
105
  }
105
- async function overwriteCodebase(setup, config) {
106
+ async function overwriteCodebase(setup) {
106
107
  let codebase;
107
108
  if (setup.config.functions.length > 1) {
108
109
  const choices = setup.config.functions.map((cfg) => ({
@@ -121,11 +122,11 @@ async function overwriteCodebase(setup, config) {
121
122
  setup.functions.source = cbconfig.source;
122
123
  setup.functions.codebase = cbconfig.codebase;
123
124
  logger_1.logger.info(`\nOverwriting ${clc.bold(`codebase ${codebase}...\n`)}`);
124
- return languageSetup(setup, config);
125
+ return languageSetup(setup);
125
126
  }
126
- async function languageSetup(setup, config) {
127
+ async function languageSetup(setup) {
127
128
  if (setup.languageOverride) {
128
- return require("./" + setup.languageOverride).setup(setup, config);
129
+ return;
129
130
  }
130
131
  const choices = [
131
132
  {
@@ -136,11 +137,13 @@ async function languageSetup(setup, config) {
136
137
  name: "TypeScript",
137
138
  value: "typescript",
138
139
  },
139
- {
140
+ ];
141
+ if (!setup.featureInfo?.dataconnectResolver) {
142
+ choices.push({
140
143
  name: "Python",
141
144
  value: "python",
142
- },
143
- ];
145
+ });
146
+ }
144
147
  const language = await (0, prompt_1.select)({
145
148
  message: "What language would you like to use to write Cloud Functions?",
146
149
  default: "javascript",
@@ -172,5 +175,10 @@ async function languageSetup(setup, config) {
172
175
  break;
173
176
  }
174
177
  setup.functions.languageChoice = language;
175
- return require("./" + language).setup(setup, config);
178
+ }
179
+ async function actuate(setup, config) {
180
+ if (setup.languageOverride) {
181
+ return require("./" + setup.languageOverride).setup(setup, config);
182
+ }
183
+ return require("./" + setup.functions.languageChoice).setup(setup, config);
176
184
  }
@@ -2,13 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setup = setup;
4
4
  const npm_dependencies_1 = require("./npm-dependencies");
5
+ const utils_1 = require("./utils");
5
6
  const prompt_1 = require("../../../prompt");
6
7
  const projectConfig_1 = require("../../../functions/projectConfig");
7
8
  const templates_1 = require("../../../templates");
8
9
  const supported = require("../../../deploy/functions/runtimes/supported");
9
10
  const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index.js");
11
+ const GRAPH_INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index-ongraphrequest.js");
10
12
  const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.lint.json");
11
13
  const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.nolint.json");
14
+ const PACKAGE_GRAPH_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package-ongraphrequest.lint.json");
15
+ const PACKAGE_GRAPH_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package-ongraphrequest.nolint.json");
12
16
  const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_eslintrc");
13
17
  const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/_gitignore");
14
18
  async function setup(setup, config) {
@@ -18,13 +22,24 @@ async function setup(setup, config) {
18
22
  if (setup.functions.lint) {
19
23
  const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
20
24
  cbconfig.predeploy = ['npm --prefix "$RESOURCE_DIR" run lint'];
21
- await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
22
25
  await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
23
26
  }
27
+ let packageTemplate = PACKAGE_LINTING_TEMPLATE;
28
+ if (setup.featureInfo?.dataconnectResolver) {
29
+ packageTemplate = setup.functions.lint
30
+ ? PACKAGE_GRAPH_LINTING_TEMPLATE
31
+ : PACKAGE_GRAPH_NO_LINTING_TEMPLATE;
32
+ }
33
+ else if (!setup.functions.lint) {
34
+ packageTemplate = PACKAGE_NO_LINTING_TEMPLATE;
35
+ }
36
+ await config.askWriteProjectFile(`${setup.functions.source}/package.json`, packageTemplate.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
37
+ if (setup.featureInfo?.dataconnectResolver) {
38
+ await config.askWriteProjectFile(`${setup.functions.source}/index.js`, (0, utils_1.templateWithSubbedResolverId)(setup.featureInfo.dataconnectResolver.id, GRAPH_INDEX_TEMPLATE));
39
+ }
24
40
  else {
25
- await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
41
+ await config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
26
42
  }
27
- await config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
28
43
  await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
29
44
  await (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
30
45
  }
@@ -2,16 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setup = setup;
4
4
  const npm_dependencies_1 = require("./npm-dependencies");
5
+ const utils_1 = require("./utils");
5
6
  const prompt_1 = require("../../../prompt");
6
7
  const projectConfig_1 = require("../../../functions/projectConfig");
7
8
  const templates_1 = require("../../../templates");
8
9
  const supported = require("../../../deploy/functions/runtimes/supported");
9
10
  const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.lint.json");
10
11
  const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.nolint.json");
12
+ const PACKAGE_GRAPH_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package-ongraphrequest.lint.json");
13
+ const PACKAGE_GRAPH_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package-ongraphrequest.nolint.json");
11
14
  const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
12
15
  const TSCONFIG_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.json");
13
16
  const TSCONFIG_DEV_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/tsconfig.dev.json");
14
17
  const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/index.ts");
18
+ const GRAPH_INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/index-ongraphrequest.ts");
15
19
  const GITIGNORE_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_gitignore");
16
20
  async function setup(setup, config) {
17
21
  setup.functions.lint =
@@ -25,16 +29,29 @@ async function setup(setup, config) {
25
29
  if (setup.functions.lint) {
26
30
  cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run lint');
27
31
  cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
28
- await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
29
32
  await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
30
33
  await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.dev.json`, TSCONFIG_DEV_TEMPLATE);
31
34
  }
32
35
  else {
33
36
  cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
34
- await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
35
37
  }
38
+ let packageTemplate = PACKAGE_LINTING_TEMPLATE;
39
+ if (setup.featureInfo?.dataconnectResolver) {
40
+ packageTemplate = setup.functions.lint
41
+ ? PACKAGE_GRAPH_LINTING_TEMPLATE
42
+ : PACKAGE_GRAPH_NO_LINTING_TEMPLATE;
43
+ }
44
+ else if (!setup.functions.lint) {
45
+ packageTemplate = PACKAGE_NO_LINTING_TEMPLATE;
46
+ }
47
+ await config.askWriteProjectFile(`${setup.functions.source}/package.json`, packageTemplate.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
36
48
  await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.json`, TSCONFIG_TEMPLATE);
37
- await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
49
+ if (setup.featureInfo?.dataconnectResolver) {
50
+ await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, (0, utils_1.templateWithSubbedResolverId)(setup.featureInfo.dataconnectResolver.id, GRAPH_INDEX_TEMPLATE));
51
+ }
52
+ else {
53
+ await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
54
+ }
38
55
  await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
39
56
  await (0, npm_dependencies_1.askInstallDependencies)(setup.functions, config);
40
57
  }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templateWithSubbedResolverId = templateWithSubbedResolverId;
4
+ function templateWithSubbedResolverId(resolverId, template) {
5
+ let replaced = template;
6
+ const resolverIdWithUnderscores = resolverId.replaceAll("-", "_");
7
+ replaced = replaced.replace("__resolverId__", resolverId);
8
+ replaced = replaced.replace("__resolverIdWithUnderscores__", resolverIdWithUnderscores);
9
+ return replaced;
10
+ }
@@ -9,7 +9,7 @@ const fs = require("fs");
9
9
  const path = require("path");
10
10
  const semver = require("semver");
11
11
  const clc = require("colorette");
12
- const functions_1 = require("../functions");
12
+ const functions = require("../functions");
13
13
  const prompt_1 = require("../../../prompt");
14
14
  const spawn_1 = require("../../spawn");
15
15
  const projectUtils_1 = require("../../../projectUtils");
@@ -114,7 +114,8 @@ async function doSetup(initSetup, config, options) {
114
114
  return;
115
115
  }
116
116
  setup.languageOverride = "typescript";
117
- await (0, functions_1.doSetup)(setup, config, options);
117
+ await functions.askQuestions(setup, config, options);
118
+ await functions.actuate(setup, config);
118
119
  delete setup.languageOverride;
119
120
  logger_1.logger.info();
120
121
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.functions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
3
+ exports.authActuate = exports.authAskQuestions = exports.aiLogicActuate = exports.aiLogicAskQuestions = exports.aitools = exports.apptestingAcutate = exports.apptestingAskQuestions = exports.genkit = exports.apphosting = exports.dataconnectResolverActuate = exports.dataconnectResolverAskQuestions = exports.dataconnectSdkActuate = exports.dataconnectSdkAskQuestions = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storageActuate = exports.storageAskQuestions = exports.hostingActuate = exports.hostingAskQuestions = exports.functionsActuate = exports.functionsAskQuestions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
4
4
  var account_1 = require("./account");
5
5
  Object.defineProperty(exports, "account", { enumerable: true, get: function () { return account_1.doSetup; } });
6
6
  var database_1 = require("./database");
@@ -10,7 +10,8 @@ var firestore_1 = require("./firestore");
10
10
  Object.defineProperty(exports, "firestoreAskQuestions", { enumerable: true, get: function () { return firestore_1.askQuestions; } });
11
11
  Object.defineProperty(exports, "firestoreActuate", { enumerable: true, get: function () { return firestore_1.actuate; } });
12
12
  var functions_1 = require("./functions");
13
- Object.defineProperty(exports, "functions", { enumerable: true, get: function () { return functions_1.doSetup; } });
13
+ Object.defineProperty(exports, "functionsAskQuestions", { enumerable: true, get: function () { return functions_1.askQuestions; } });
14
+ Object.defineProperty(exports, "functionsActuate", { enumerable: true, get: function () { return functions_1.actuate; } });
14
15
  var hosting_1 = require("./hosting");
15
16
  Object.defineProperty(exports, "hostingAskQuestions", { enumerable: true, get: function () { return hosting_1.askQuestions; } });
16
17
  Object.defineProperty(exports, "hostingActuate", { enumerable: true, get: function () { return hosting_1.actuate; } });
@@ -48,3 +49,6 @@ Object.defineProperty(exports, "aitools", { enumerable: true, get: function () {
48
49
  var ailogic_1 = require("./ailogic");
49
50
  Object.defineProperty(exports, "aiLogicAskQuestions", { enumerable: true, get: function () { return ailogic_1.askQuestions; } });
50
51
  Object.defineProperty(exports, "aiLogicActuate", { enumerable: true, get: function () { return ailogic_1.actuate; } });
52
+ var auth_1 = require("./auth");
53
+ Object.defineProperty(exports, "authAskQuestions", { enumerable: true, get: function () { return auth_1.askQuestions; } });
54
+ Object.defineProperty(exports, "authActuate", { enumerable: true, get: function () { return auth_1.actuate; } });
package/lib/init/index.js CHANGED
@@ -35,7 +35,11 @@ const featuresList = [
35
35
  askQuestions: features.dataconnectResolverAskQuestions,
36
36
  actuate: features.dataconnectResolverActuate,
37
37
  },
38
- { name: "functions", doSetup: features.functions },
38
+ {
39
+ name: "functions",
40
+ askQuestions: features.functionsAskQuestions,
41
+ actuate: features.functionsActuate,
42
+ },
39
43
  {
40
44
  name: "hosting",
41
45
  askQuestions: features.hostingAskQuestions,
@@ -64,6 +68,12 @@ const featuresList = [
64
68
  actuate: features.aiLogicActuate,
65
69
  },
66
70
  { name: "aitools", displayName: "AI Tools", doSetup: features.aitools },
71
+ {
72
+ name: "auth",
73
+ displayName: "Authentication",
74
+ askQuestions: features.authAskQuestions,
75
+ actuate: features.authActuate,
76
+ },
67
77
  ];
68
78
  const featureMap = new Map(featuresList.map((feature) => [feature.name, feature]));
69
79
  async function init(setup, config, options) {
@@ -80,6 +80,9 @@ function buildProvisionRequest(options) {
80
80
  ...(options.features?.firebaseAiLogicInput && {
81
81
  firebaseAiLogicInput: options.features.firebaseAiLogicInput,
82
82
  }),
83
+ ...(options.features?.firebaseAuthInput && {
84
+ firebaseAuthInput: options.features.firebaseAuthInput,
85
+ }),
83
86
  ...platformInput,
84
87
  };
85
88
  }
@@ -1,2 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderMode = void 0;
4
+ var ProviderMode;
5
+ (function (ProviderMode) {
6
+ ProviderMode["PROVIDER_MODE_UNSPECIFIED"] = "PROVIDER_MODE_UNSPECIFIED";
7
+ ProviderMode["PROVIDER_ENABLED"] = "PROVIDER_ENABLED";
8
+ ProviderMode["PROVIDER_DISABLED"] = "PROVIDER_DISABLED";
9
+ })(ProviderMode || (exports.ProviderMode = ProviderMode = {}));
@@ -18,8 +18,25 @@ exports.init_auth = (0, resource_1.resource)({
18
18
 
19
19
  **Permission & Setup:**
20
20
  - Request developer permission before implementing sign-up and login features
21
- - Guide developers to enable authentication providers (Email/Password, Google Sign-in, etc.) in the [Firebase Auth Console](https://console.firebase.google.com/)
22
- - Ask developers to confirm which authentication method they selected before proceeding
21
+ - Configure authentication providers in \`firebase.json\`:
22
+ \`\`\`json
23
+ {
24
+ "auth": {
25
+ "providers": {
26
+ "emailPassword": true,
27
+ "googleSignIn": {
28
+ "oAuthBrandDisplayName": "My App",
29
+ "supportEmail": "support@example.com",
30
+ "authorizedRedirectUris": [
31
+ "https://example-website.com",
32
+ "http://localhost:4000"
33
+ ]
34
+ }
35
+ }
36
+ }
37
+ }
38
+ \`\`\`
39
+ - Run \`firebase deploy --only auth\` to enable the configured providers
23
40
 
24
41
  **Implementation:**
25
42
  - Create sign-up and login pages using Firebase Authentication
@@ -92,8 +92,10 @@ exports.check_status = (0, tool_1.tool)("apptesting", {
92
92
  if (getAvailableDevices) {
93
93
  devices = await (0, apptesting_1.testEnvironmentCatalog)(projectId || "", "ANDROID");
94
94
  }
95
- return (0, util_1.toContent)({
96
- devices,
97
- releaseTest,
98
- });
95
+ const result = {};
96
+ if (devices)
97
+ result.devices = devices;
98
+ if (releaseTest)
99
+ result.releaseTest = releaseTest;
100
+ return (0, util_1.toContent)(result);
99
101
  });
@@ -129,6 +129,27 @@ exports.init = (0, tool_1.tool)("core", {
129
129
  })
130
130
  .optional()
131
131
  .describe("Provide this object to initialize Firebase Hosting in this project directory."),
132
+ auth: zod_1.z
133
+ .object({
134
+ providers: zod_1.z.object({
135
+ emailPassword: zod_1.z
136
+ .boolean()
137
+ .optional()
138
+ .describe("Enable Email/Password authentication."),
139
+ anonymous: zod_1.z.boolean().optional().describe("Enable Anonymous authentication."),
140
+ googleSignIn: zod_1.z
141
+ .object({
142
+ oAuthBrandDisplayName: zod_1.z
143
+ .string()
144
+ .describe("The display name for the OAuth brand."),
145
+ supportEmail: zod_1.z.string().describe("The support email for the OAuth brand."),
146
+ })
147
+ .optional()
148
+ .describe("Configure Google Sign-In."),
149
+ }),
150
+ })
151
+ .optional()
152
+ .describe("Provide this object to initialize Firebase Authentication."),
132
153
  }),
133
154
  }),
134
155
  annotations: {
@@ -202,6 +223,16 @@ exports.init = (0, tool_1.tool)("core", {
202
223
  spa: features.hosting.single_page_app,
203
224
  };
204
225
  }
226
+ if (features.auth) {
227
+ featuresList.push("auth");
228
+ featureInfo.auth = {
229
+ providers: {
230
+ anonymous: features.auth.providers.anonymous,
231
+ emailPassword: features.auth.providers.emailPassword,
232
+ googleSignIn: features.auth.providers.googleSignIn,
233
+ },
234
+ };
235
+ }
205
236
  const setup = {
206
237
  config: config?.src,
207
238
  rcfile: rc?.data,