firebase-tools 12.4.2 → 12.4.4

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.
package/lib/apiv2.js CHANGED
@@ -233,6 +233,7 @@ class Client {
233
233
  }
234
234
  catch (thrown) {
235
235
  const err = thrown instanceof Error ? thrown : new Error(thrown);
236
+ logger_1.logger.debug(`*** [apiv2] error from fetch(${fetchURL}, ${JSON.stringify(fetchOptions)}): ${err}`);
236
237
  const isAbortError = err.name.includes("AbortError");
237
238
  if (isAbortError) {
238
239
  throw new error_1.FirebaseError(`Timeout reached making request to ${fetchURL}`, {
@@ -1,76 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
- const command_1 = require("../command");
5
4
  const Table = require("cli-table");
5
+ const command_1 = require("../command");
6
6
  const clc = require("colorette");
7
7
  const ora = require("ora");
8
8
  const logger_1 = require("../logger");
9
9
  const requirePermissions_1 = require("../requirePermissions");
10
- const projectUtils_1 = require("../projectUtils");
11
- const firedata = require("../gcp/firedata");
12
10
  const types_1 = require("../emulator/types");
13
11
  const commandUtils_1 = require("../emulator/commandUtils");
14
12
  const experiments = require("../experiments");
15
- const projectUtils_2 = require("../projectUtils");
13
+ const projectUtils_1 = require("../projectUtils");
16
14
  const database_1 = require("../management/database");
17
- function logInstances(instances) {
18
- if (instances.length === 0) {
19
- logger_1.logger.info(clc.bold("No database instances found."));
20
- return;
21
- }
22
- const tableHead = ["Database Instance Name", "Location", "Type", "State"];
23
- const table = new Table({ head: tableHead, style: { head: ["green"] } });
24
- instances.forEach((db) => {
25
- table.push([db.name, db.location, db.type, db.state]);
26
- });
27
- logger_1.logger.info(table.toString());
28
- }
29
- function logInstancesCount(count = 0) {
30
- if (count === 0) {
31
- return;
32
- }
33
- logger_1.logger.info("");
34
- logger_1.logger.info(`${count} database instance(s) total.`);
35
- }
36
15
  exports.command = new command_1.Command("database:instances:list")
37
16
  .description("list realtime database instances, optionally filtered by a specified location")
38
17
  .before(requirePermissions_1.requirePermissions, ["firebasedatabase.instances.list"])
18
+ .option("-l, --location <location>", "(optional) location for the database instance, defaults to all regions")
39
19
  .before(commandUtils_1.warnEmulatorNotSupported, types_1.Emulators.DATABASE)
40
20
  .action(async (options) => {
41
21
  const location = (0, database_1.parseDatabaseLocation)(options.location, database_1.DatabaseLocation.ANY);
42
22
  const spinner = ora("Preparing the list of your Firebase Realtime Database instances" +
43
23
  `${location === database_1.DatabaseLocation.ANY ? "" : ` for location: ${location}`}`).start();
44
- let instances;
45
- if (experiments.isEnabled("rtdbmanagement")) {
46
- const projectId = (0, projectUtils_2.needProjectId)(options);
47
- try {
48
- instances = await (0, database_1.listDatabaseInstances)(projectId, location);
49
- }
50
- catch (err) {
51
- spinner.fail();
52
- throw err;
53
- }
54
- spinner.succeed();
55
- logInstances(instances);
56
- logInstancesCount(instances.length);
57
- return instances;
58
- }
59
- const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
24
+ const projectId = (0, projectUtils_1.needProjectId)(options);
25
+ let instances = [];
60
26
  try {
61
- instances = await firedata.listDatabaseInstances(projectNumber);
27
+ instances = await (0, database_1.listDatabaseInstances)(projectId, location);
62
28
  }
63
29
  catch (err) {
64
30
  spinner.fail();
65
31
  throw err;
66
32
  }
67
33
  spinner.succeed();
68
- for (const instance of instances) {
69
- logger_1.logger.info(instance.instance);
34
+ if (instances.length === 0) {
35
+ logger_1.logger.info(clc.bold("No database instances found."));
36
+ return;
37
+ }
38
+ if (!experiments.isEnabled("rtdbmanagement")) {
39
+ for (const instance of instances) {
40
+ logger_1.logger.info(instance.name);
41
+ }
42
+ logger_1.logger.info(`Project ${options.project} has ${instances.length} database instances`);
43
+ return instances;
70
44
  }
71
- logger_1.logger.info(`Project ${options.project} has ${instances.length} database instances`);
45
+ const tableHead = ["Database Instance Name", "Location", "Type", "State"];
46
+ const table = new Table({ head: tableHead, style: { head: ["green"] } });
47
+ for (const db of instances) {
48
+ table.push([db.name, db.location, db.type, db.state]);
49
+ }
50
+ logger_1.logger.info(table.toString());
51
+ logger_1.logger.info(`${instances.length} database instance(s) total.`);
72
52
  return instances;
73
53
  });
74
- if (experiments.isEnabled("rtdbmanagement")) {
75
- exports.command = exports.command.option("-l, --location <location>", "(optional) location for the database instance, defaults to us-central1");
76
- }
@@ -144,8 +144,6 @@ function load(client) {
144
144
  client.internaltesting.frameworks.compose = loadCommand("internaltesting-frameworks-compose");
145
145
  client.internaltesting.functions = {};
146
146
  client.internaltesting.functions.discover = loadCommand("internaltesting-functions-discover");
147
- client.internaltesting.frameworks = {};
148
- client.internaltesting.frameworks.init = loadCommand("internaltesting-frameworks-init");
149
147
  }
150
148
  client.login = loadCommand("login");
151
149
  client.login.add = loadCommand("login-add");
@@ -6,15 +6,17 @@ const logger_1 = require("../logger");
6
6
  const driver_1 = require("../frameworks/compose/driver");
7
7
  const compose_1 = require("../frameworks/compose");
8
8
  const error_1 = require("../error");
9
+ const filesystem_1 = require("../frameworks/compose/discover/filesystem");
10
+ const frameworkSpec_1 = require("../frameworks/compose/discover/frameworkSpec");
9
11
  exports.command = new command_1.Command("internaltesting:frameworks:compose")
10
12
  .option("-m, --mode <mode>", "Composer mode (local or docker)", "local")
11
13
  .description("compose framework in current directory")
12
- .action((options) => {
14
+ .action(async (options) => {
13
15
  const mode = options.mode;
14
16
  if (!driver_1.SUPPORTED_MODES.includes(mode)) {
15
17
  throw new error_1.FirebaseError(`Unsupported mode ${mode}. Supported modes are [${driver_1.SUPPORTED_MODES.join(", ")}]`);
16
18
  }
17
- const bundle = (0, compose_1.compose)(mode);
19
+ const bundle = await (0, compose_1.compose)(mode, new filesystem_1.LocalFileSystem("."), frameworkSpec_1.frameworkSpecs);
18
20
  logger_1.logger.info(JSON.stringify(bundle, null, 2));
19
21
  return {};
20
22
  });
@@ -16,7 +16,7 @@ const LINKS = [
16
16
  { name: "Analytics", arg: "analytics", consolePath: "/analytics" },
17
17
  { name: "Authentication: Providers", arg: "auth", consolePath: "/authentication/providers" },
18
18
  { name: "Authentication: Users", arg: "auth:users", consolePath: "/authentication/users" },
19
- { name: "Crash Reporting", arg: "crash", consolePath: "/monitoring" },
19
+ { name: "Crash Reporting", arg: "crash", consolePath: "/crashlytics" },
20
20
  { name: "Database: Data", arg: "database", consolePath: "/database/data" },
21
21
  { name: "Database: Rules", arg: "database:rules", consolePath: "/database/rules" },
22
22
  { name: "Docs", arg: "docs", url: "https://firebase.google.com/docs" },
@@ -38,7 +38,7 @@ const LINKS = [
38
38
  { name: "Functions", arg: "functions", consolePath: "/functions/list" },
39
39
  { name: "Functions Log", arg: "functions:log" },
40
40
  { name: "Hosting: Deployed Site", arg: "hosting:site" },
41
- { name: "Hosting", arg: "hosting", consolePath: "/hosting/main" },
41
+ { name: "Hosting", arg: "hosting", consolePath: "/hosting/sites" },
42
42
  { name: "Notifications", arg: "notifications", consolePath: "/notification" },
43
43
  { name: "Project Dashboard", arg: "dashboard", consolePath: "/overview" },
44
44
  { name: "Project Settings", arg: "settings", consolePath: "/settings/general" },
@@ -295,7 +295,7 @@ async function loadCodebases(config, options, firebaseConfig, runtimeConfig, fil
295
295
  logger_1.logger.debug(`Building ${runtimeDelegate.name} source`);
296
296
  await runtimeDelegate.build();
297
297
  const firebaseEnvs = functionsEnv.loadFirebaseEnvs(firebaseConfig, projectId);
298
- (0, utils_1.logLabeledBullet)("functions", `Loading and anaylzing source code for codebase ${codebase} to determine what to deploy`);
298
+ (0, utils_1.logLabeledBullet)("functions", `Loading and analyzing source code for codebase ${codebase} to determine what to deploy`);
299
299
  wantBuilds[codebase] = await runtimeDelegate.discoverBuild(runtimeConfig, Object.assign(Object.assign({}, firebaseEnvs), { GOOGLE_CLOUD_QUOTA_PROJECT: projectId }));
300
300
  wantBuilds[codebase].runtime = codebaseConfig.runtime;
301
301
  }
@@ -35,9 +35,9 @@ const EMULATOR_UPDATE_DETAILS = {
35
35
  ui: experiments.isEnabled("emulatoruisnapshot")
36
36
  ? { version: "SNAPSHOT", expectedSize: -1, expectedChecksum: "" }
37
37
  : {
38
- version: "1.11.6",
39
- expectedSize: 3063444,
40
- expectedChecksum: "14b971f4ed4909f348e647db7114d62b",
38
+ version: "1.11.7",
39
+ expectedSize: 3064105,
40
+ expectedChecksum: "bd2bcc331cbf613a5b3b55a1ce08998b",
41
41
  },
42
42
  pubsub: {
43
43
  version: "0.7.1",
@@ -84,7 +84,7 @@ class RuntimeWorker {
84
84
  });
85
85
  });
86
86
  }
87
- request(req, resp, body) {
87
+ request(req, resp, body, debug) {
88
88
  if (this.triggerKey !== FREE_WORKER_KEY) {
89
89
  this.logInfo(`Beginning execution of "${this.triggerKey}"`);
90
90
  }
@@ -124,6 +124,10 @@ class RuntimeWorker {
124
124
  const piped = _resp.pipe(resp);
125
125
  piped.on("finish", () => finishReq("finish"));
126
126
  });
127
+ if (debug) {
128
+ proxy.setSocketKeepAlive(false);
129
+ proxy.setTimeout(0);
130
+ }
127
131
  proxy.on("timeout", () => {
128
132
  this.logger.log("ERROR", `Your function timed out after ~${this.timeoutSeconds}s. To configure this timeout, see
129
133
  https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.`);
@@ -260,7 +264,7 @@ class RuntimeWorkerPool {
260
264
  if (debug) {
261
265
  await worker.sendDebugMsg(debug);
262
266
  }
263
- return worker.request(req, resp, body);
267
+ return worker.request(req, resp, body, !!debug);
264
268
  }
265
269
  getIdleWorker(triggerId) {
266
270
  this.cleanUpWorkers();
@@ -4,7 +4,7 @@ exports.readOrNull = exports.LocalFileSystem = void 0;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const path = require("path");
6
6
  const error_1 = require("../../../error");
7
- const logger_1 = require("../../../../src/logger");
7
+ const logger_1 = require("../../../logger");
8
8
  class LocalFileSystem {
9
9
  constructor(cwd) {
10
10
  this.cwd = cwd;
@@ -1,23 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.discover = void 0;
4
- function discover() {
5
- return {
6
- baseImage: "us-docker.pkg.dev/firestack-build/test/run:latest",
7
- environmentVariables: {
8
- NODE_ENV: "PRODUCTION",
9
- },
10
- installCommand: "npm install",
11
- buildCommand: "npm run build",
12
- startCommand: "npm run start",
13
- afterInstall: (b) => {
14
- console.log("HOOK: AFTER INSTALL");
15
- return Object.assign(Object.assign({}, b), { version: "v1alpha", notes: "afterInstall" });
16
- },
17
- afterBuild(b) {
18
- console.log("HOOK: AFTER BUILD");
19
- return Object.assign(Object.assign({}, b), { version: "v1alpha", notes: "afterBuild" });
20
- },
21
- };
4
+ const node_1 = require("./runtime/node");
5
+ const error_1 = require("../../../error");
6
+ const supportedRuntimes = [new node_1.NodejsRuntime()];
7
+ async function discover(fs, allFrameworkSpecs) {
8
+ try {
9
+ let discoveredRuntime = undefined;
10
+ for (const runtime of supportedRuntimes) {
11
+ if (await runtime.match(fs)) {
12
+ if (!discoveredRuntime) {
13
+ discoveredRuntime = runtime;
14
+ }
15
+ else {
16
+ throw new error_1.FirebaseError(`Conflit occurred as multiple runtimes ${discoveredRuntime.getRuntimeName()}, ${runtime.getRuntimeName()} are discovered in the application.`);
17
+ }
18
+ }
19
+ }
20
+ if (!discoveredRuntime) {
21
+ throw new error_1.FirebaseError(`Unable to determine the specific runtime for the application. The supported runtime options include ${supportedRuntimes
22
+ .map((x) => x.getRuntimeName())
23
+ .join(" , ")}.`);
24
+ }
25
+ const runtimeSpec = await discoveredRuntime.analyseCodebase(fs, allFrameworkSpecs);
26
+ return runtimeSpec;
27
+ }
28
+ catch (error) {
29
+ throw new error_1.FirebaseError(`Failed to identify required specifications to execute the application: ${error}`);
30
+ }
22
31
  }
23
32
  exports.discover = discover;
@@ -4,7 +4,7 @@ exports.NodejsRuntime = void 0;
4
4
  const filesystem_1 = require("../filesystem");
5
5
  const frameworkMatcher_1 = require("../frameworkMatcher");
6
6
  const error_1 = require("../../../../error");
7
- const logger_1 = require("../../../../../src/logger");
7
+ const logger_1 = require("../../../../logger");
8
8
  const utils_1 = require("../../../utils");
9
9
  const supportedNodeVersions = ["18"];
10
10
  const NODE_RUNTIME_ID = "nodejs";
@@ -13,7 +13,6 @@ const YARN_LOCK = "yarn.lock";
13
13
  class NodejsRuntime {
14
14
  constructor() {
15
15
  this.runtimeRequiredFiles = [PACKAGE_JSON];
16
- this.contentCache = {};
17
16
  }
18
17
  async match(fs) {
19
18
  const areAllFilesPresent = await Promise.all(this.runtimeRequiredFiles.map((file) => fs.exists(file)));
@@ -24,13 +23,13 @@ class NodejsRuntime {
24
23
  }
25
24
  getNodeImage(engine) {
26
25
  if (!engine || !engine.node) {
27
- return `node:${supportedNodeVersions[supportedNodeVersions.length - 1]}-slim`;
26
+ return "us-docker.pkg.dev/firestack-build/test/run";
28
27
  }
29
28
  const versionNumber = engine.node;
30
29
  if (!supportedNodeVersions.includes(versionNumber)) {
31
30
  throw new error_1.FirebaseError(`This integration expects Node version ${(0, utils_1.conjoinOptions)(supportedNodeVersions, "or")}. You're running version ${versionNumber}, which is not compatible.`);
32
31
  }
33
- return `node:${versionNumber}-slim`;
32
+ return "us-docker.pkg.dev/firestack-build/test/run";
34
33
  }
35
34
  async getPackageManager(fs) {
36
35
  try {
@@ -89,7 +89,9 @@ class DockerDriver {
89
89
  this.dockerfileBuilder.from(spec.baseImage, "base").user("firebase");
90
90
  }
91
91
  execDockerPush(args) {
92
- console.log(`executing docker build: ${args.join(" ")}`);
92
+ console.debug(JSON.stringify({ message: `executing docker build: ${args.join(" ")}` }));
93
+ console.info(JSON.stringify({ foo: "bar", message: `executing docker build: ${args.join(" ")}` }));
94
+ console.error(JSON.stringify({ message: `executing docker build: ${args.join(" ")}` }));
93
95
  return spawn.sync("docker", ["push", ...args], {
94
96
  stdio: ["pipe", "inherit", "inherit"],
95
97
  });
@@ -126,20 +128,28 @@ class DockerDriver {
126
128
  return JSON.parse(fs.readFileSync("./.firebase/.output/bundle.json", "utf8"));
127
129
  }
128
130
  install() {
129
- this.dockerfileBuilder
130
- .fromLastStage(DOCKER_STAGE_INSTALL)
131
- .workdir("/home/firebase/app")
132
- .envs(this.spec.environmentVariables || {})
133
- .copyForFirebase("package.json", ".")
134
- .run(this.spec.installCommand);
135
- this.buildStage(DOCKER_STAGE_INSTALL, ".");
131
+ if (this.spec.installCommand) {
132
+ this.dockerfileBuilder
133
+ .fromLastStage(DOCKER_STAGE_INSTALL)
134
+ .workdir("/home/firebase/app")
135
+ .envs(this.spec.environmentVariables || {})
136
+ .copyForFirebase("package.json", ".");
137
+ if (this.spec.packageManagerInstallCommand) {
138
+ this.dockerfileBuilder.run(this.spec.packageManagerInstallCommand);
139
+ }
140
+ this.dockerfileBuilder.run(this.spec.installCommand);
141
+ this.buildStage(DOCKER_STAGE_INSTALL, ".");
142
+ }
136
143
  }
137
144
  build() {
138
- this.dockerfileBuilder
139
- .fromLastStage(DOCKER_STAGE_BUILD)
140
- .copyForFirebase(".", ".")
141
- .run(this.spec.buildCommand);
142
- this.buildStage(DOCKER_STAGE_BUILD, ".");
145
+ var _a;
146
+ if ((_a = this.spec.detectedCommands) === null || _a === void 0 ? void 0 : _a.build) {
147
+ this.dockerfileBuilder
148
+ .fromLastStage(DOCKER_STAGE_BUILD)
149
+ .copyForFirebase(".", ".")
150
+ .run(this.spec.detectedCommands.build.cmd);
151
+ this.buildStage(DOCKER_STAGE_BUILD, ".");
152
+ }
143
153
  }
144
154
  export(bundle) {
145
155
  var _a;
@@ -18,12 +18,21 @@ class LocalDriver {
18
18
  }
19
19
  }
20
20
  install() {
21
- const [cmd, ...args] = this.spec.installCommand.split(" ");
22
- this.execCmd(cmd, args);
21
+ if (this.spec.installCommand) {
22
+ if (this.spec.packageManagerInstallCommand) {
23
+ const [cmd, ...args] = this.spec.packageManagerInstallCommand.split(" ");
24
+ this.execCmd(cmd, args);
25
+ }
26
+ const [cmd, ...args] = this.spec.installCommand.split(" ");
27
+ this.execCmd(cmd, args);
28
+ }
23
29
  }
24
30
  build() {
25
- const [cmd, ...args] = this.spec.buildCommand.split(" ");
26
- this.execCmd(cmd, args);
31
+ var _a;
32
+ if ((_a = this.spec.detectedCommands) === null || _a === void 0 ? void 0 : _a.build) {
33
+ const [cmd, ...args] = this.spec.detectedCommands.build.cmd.split(" ");
34
+ this.execCmd(cmd, args);
35
+ }
27
36
  }
28
37
  export(bundle) {
29
38
  }
@@ -3,24 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.compose = void 0;
4
4
  const driver_1 = require("./driver");
5
5
  const discover_1 = require("./discover");
6
- function compose(mode) {
6
+ async function compose(mode, fs, allFrameworkSpecs) {
7
+ var _a, _b, _c, _d;
7
8
  let bundle = { version: "v1alpha" };
8
- const spec = (0, discover_1.discover)();
9
+ const spec = await (0, discover_1.discover)(fs, allFrameworkSpecs);
9
10
  const driver = (0, driver_1.getDriver)(mode, spec);
10
- if (spec.startCommand) {
11
+ if ((_a = spec.detectedCommands) === null || _a === void 0 ? void 0 : _a.run) {
11
12
  bundle.server = {
12
13
  start: {
13
- cmd: spec.startCommand.split(" "),
14
+ cmd: spec.detectedCommands.run.cmd.split(" "),
14
15
  },
15
16
  };
16
17
  }
17
18
  driver.install();
18
- if (spec.afterInstall) {
19
- bundle = driver.execHook(bundle, spec.afterInstall);
19
+ if ((_b = spec.frameworkHooks) === null || _b === void 0 ? void 0 : _b.afterInstall) {
20
+ bundle = driver.execHook(bundle, spec.frameworkHooks.afterInstall);
20
21
  }
21
22
  driver.build();
22
- if (spec.afterBuild) {
23
- bundle = driver.execHook(bundle, spec.afterBuild);
23
+ if ((_c = spec.frameworkHooks) === null || _c === void 0 ? void 0 : _c.afterBuild) {
24
+ bundle = driver.execHook(bundle, (_d = spec.frameworkHooks) === null || _d === void 0 ? void 0 : _d.afterBuild);
24
25
  }
25
26
  if (bundle.server) {
26
27
  driver.export(bundle);
@@ -48,16 +48,25 @@ async function discover(dir) {
48
48
  exports.discover = discover;
49
49
  async function build(dir) {
50
50
  var _a, _b;
51
- const { default: nextBuild } = (0, utils_1.relativeRequire)(dir, "next/dist/build");
52
51
  await (0, utils_1.warnIfCustomBuildScript)(dir, exports.name, DEFAULT_BUILD_SCRIPT);
53
52
  const reactVersion = getReactVersion(dir);
54
53
  if (reactVersion && (0, semver_1.gte)(reactVersion, "18.0.0")) {
55
54
  process.env.__NEXT_REACT_ROOT = "true";
56
55
  }
57
- await nextBuild(dir, null, false, false, true).catch((e) => {
58
- console.error(e.message);
59
- throw e;
56
+ const cli = (0, utils_1.getNodeModuleBin)("next", dir);
57
+ const nextBuild = new Promise((resolve, reject) => {
58
+ var _a, _b;
59
+ const buildProcess = (0, cross_spawn_1.spawn)(cli, ["build"], { cwd: dir });
60
+ (_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", (data) => logger_1.logger.info(data.toString()));
61
+ (_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on("data", (data) => logger_1.logger.info(data.toString()));
62
+ buildProcess.on("error", (err) => {
63
+ reject(new error_1.FirebaseError(`Unable to build your Next.js app: ${err}`));
64
+ });
65
+ buildProcess.on("exit", (code) => {
66
+ resolve(code);
67
+ });
60
68
  });
69
+ await nextBuild;
61
70
  const reasonsForBackend = new Set();
62
71
  const { distDir, trailingSlash, basePath: baseUrl } = await getConfig(dir);
63
72
  if (await (0, utils_2.isUsingMiddleware)((0, path_1.join)(dir, distDir), false)) {
@@ -7,7 +7,7 @@ const _ = require("lodash");
7
7
  const request = require("request");
8
8
  const util = require("util");
9
9
  const functions_1 = require("./serve/functions");
10
- const LocalFunction = require("./localFunction");
10
+ const localFunction_1 = require("./localFunction");
11
11
  const utils = require("./utils");
12
12
  const logger_1 = require("./logger");
13
13
  const shell = require("./emulator/functionsEmulatorShell");
@@ -73,9 +73,9 @@ const actionFunction = async (options) => {
73
73
  const initializeContext = (context) => {
74
74
  for (const trigger of emulator.triggers) {
75
75
  if (emulator.emulatedFunctions.includes(trigger.id)) {
76
- const localFunction = new LocalFunction(trigger, emulator.urls, emulator);
76
+ const localFunction = new localFunction_1.default(trigger, emulator.urls, emulator);
77
77
  const triggerNameDotNotation = trigger.name.replace(/-/g, ".");
78
- _.set(context, triggerNameDotNotation, localFunction.call);
78
+ _.set(context, triggerNameDotNotation, localFunction.makeFn());
79
79
  }
80
80
  }
81
81
  context.help =
@@ -3,19 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBuild = exports.createStack = exports.API_VERSION = void 0;
4
4
  const apiv2_1 = require("../apiv2");
5
5
  const api_1 = require("../api");
6
- exports.API_VERSION = "v1";
6
+ exports.API_VERSION = "v2";
7
7
  const client = new apiv2_1.Client({
8
8
  urlPrefix: api_1.frameworksOrigin,
9
9
  auth: true,
10
10
  apiVersion: exports.API_VERSION,
11
11
  });
12
- async function createStack(projectId, location, stackId, stack) {
13
- const res = await client.post(`projects/${projectId}/locations/${location}/stacks`, stack, { queryParams: { stackId } });
12
+ async function createStack(projectId, location, stackInput) {
13
+ const stackId = stackInput.name;
14
+ const res = await client.post(`projects/${projectId}/locations/${location}/stacks`, stackInput, { queryParams: { stackId } });
14
15
  return res.body;
15
16
  }
16
17
  exports.createStack = createStack;
17
- async function createBuild(projectId, location, stackId, buildId, build) {
18
- const res = await client.post(`projects/${projectId}/locations/${location}/stacks/${stackId}/builds`, build, { queryParams: { buildId } });
18
+ async function createBuild(projectId, location, stackId, buildInput) {
19
+ const buildId = buildInput.name;
20
+ const res = await client.post(`projects/${projectId}/locations/${location}/stacks/${stackId}/builds`, buildInput, { queryParams: { buildId } });
19
21
  return res.body;
20
22
  }
21
23
  exports.createBuild = createBuild;
@@ -1,12 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.doSetup = void 0;
3
+ exports.createStack = exports.doSetup = void 0;
4
4
  const clc = require("colorette");
5
5
  const utils = require("../../../utils");
6
6
  const logger_1 = require("../../../logger");
7
7
  const prompt_1 = require("../../../prompt");
8
8
  const constants_1 = require("./constants");
9
+ const repo_1 = require("./repo");
10
+ const poller = require("../../../operation-poller");
11
+ const api_1 = require("../../../api");
12
+ const gcp = require("../../../gcp/frameworks");
13
+ const frameworks_1 = require("../../../gcp/frameworks");
14
+ const frameworksPollerOptions = {
15
+ apiOrigin: api_1.frameworksOrigin,
16
+ apiVersion: frameworks_1.API_VERSION,
17
+ masterTimeout: 25 * 60 * 1000,
18
+ maxBackoff: 10000,
19
+ };
9
20
  async function doSetup(setup) {
21
+ var _a, _b;
22
+ const projectId = (_b = (_a = setup === null || setup === void 0 ? void 0 : setup.rcfile) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.default;
10
23
  setup.frameworks = {};
11
24
  utils.logBullet("First we need a few details to create your service.");
12
25
  await (0, prompt_1.promptOnce)({
@@ -32,5 +45,22 @@ async function doSetup(setup) {
32
45
  message: "How do you want to deploy",
33
46
  choices: constants_1.ALLOWED_DEPLOY_METHODS,
34
47
  }, setup.frameworks);
48
+ if (setup.frameworks.deployMethod === "github") {
49
+ const cloudBuildConnRepo = await (0, repo_1.linkGitHubRepository)(projectId, setup.frameworks.region, setup.frameworks.serviceName);
50
+ toStack(cloudBuildConnRepo, setup.frameworks.serviceName);
51
+ }
35
52
  }
36
53
  exports.doSetup = doSetup;
54
+ function toStack(cloudBuildConnRepo, stackId) {
55
+ return {
56
+ name: stackId,
57
+ codebase: { repository: cloudBuildConnRepo.name, rootDirectory: "/" },
58
+ labels: {},
59
+ };
60
+ }
61
+ async function createStack(projectId, location, stackInput) {
62
+ const op = await gcp.createStack(projectId, location, stackInput);
63
+ const stack = await poller.pollOperation(Object.assign(Object.assign({}, frameworksPollerOptions), { pollerName: `create-${projectId}-${location}-${stackInput.name}`, operationResourceName: op.name }));
64
+ return stack;
65
+ }
66
+ exports.createStack = createStack;
@@ -21,14 +21,11 @@ function extractRepoSlugFromURI(remoteUri) {
21
21
  }
22
22
  return match[1];
23
23
  }
24
- function generateConnectionId(stackId) {
25
- return `composer-${stackId}-conn`;
26
- }
27
24
  function generateRepositoryId() {
28
25
  return `composer-repo`;
29
26
  }
30
27
  async function linkGitHubRepository(projectId, location, stackId) {
31
- const connectionId = generateConnectionId(stackId);
28
+ const connectionId = stackId;
32
29
  await getOrCreateConnection(projectId, location, connectionId);
33
30
  let remoteUri = await promptRepositoryURI(projectId, location, connectionId);
34
31
  while (remoteUri === "") {
@@ -1,191 +1,204 @@
1
1
  "use strict";
2
- var _ = require("lodash");
3
- var request = require("request");
4
- var { encodeFirestoreValue } = require("./firestore/encodeFirestoreValue");
5
- var utils = require("./utils");
6
- var LocalFunction = function (trigger, urls, controller) {
7
- const isCallable = _.get(trigger, ["labels", "deployment-callable"], "false");
8
- this.id = trigger.id;
9
- this.name = trigger.name;
10
- this.eventTrigger = trigger.eventTrigger;
11
- this.httpsTrigger = trigger.httpsTrigger;
12
- this.controller = controller;
13
- this.url = _.get(urls, this.id);
14
- if (this.httpsTrigger) {
15
- if (isCallable == "true") {
16
- this.call = this._constructCallableFunc.bind(this);
17
- }
18
- else {
19
- this.call = request.defaults({
20
- callback: this._requestCallBack,
21
- baseUrl: this.url,
22
- uri: "",
23
- });
24
- }
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const request = require("request");
4
+ const utils = require("./utils");
5
+ const encodeFirestoreValue_1 = require("./firestore/encodeFirestoreValue");
6
+ class LocalFunction {
7
+ constructor(trigger, urls, controller) {
8
+ this.trigger = trigger;
9
+ this.controller = controller;
10
+ this.paramWildcardRegex = new RegExp("{[^/{}]*}", "g");
11
+ this.url = urls[trigger.id];
25
12
  }
26
- else {
27
- this.call = this._call.bind(this);
28
- }
29
- };
30
- LocalFunction.prototype._isDatabaseFunc = function (eventTrigger) {
31
- return utils.getFunctionsEventProvider(eventTrigger.eventType) === "Database";
32
- };
33
- LocalFunction.prototype._isFirestoreFunc = function (eventTrigger) {
34
- return utils.getFunctionsEventProvider(eventTrigger.eventType) === "Firestore";
35
- };
36
- LocalFunction.prototype._substituteParams = function (resource, params) {
37
- var wildcardRegex = new RegExp("{[^/{}]*}", "g");
38
- return resource.replace(wildcardRegex, function (wildcard) {
39
- var wildcardNoBraces = wildcard.slice(1, -1);
40
- var sub = _.get(params, wildcardNoBraces);
41
- return sub || wildcardNoBraces + utils.randomInt(1, 9);
42
- });
43
- };
44
- LocalFunction.prototype._constructCallableFunc = function (data, opts) {
45
- opts = opts || {};
46
- var headers = {};
47
- if (opts.instanceIdToken) {
48
- headers["Firebase-Instance-ID-Token"] = opts.instanceIdToken;
13
+ substituteParams(resource, params) {
14
+ if (!params) {
15
+ return resource;
16
+ }
17
+ return resource.replace(this.paramWildcardRegex, (wildcard) => {
18
+ const wildcardNoBraces = wildcard.slice(1, -1);
19
+ const sub = params === null || params === void 0 ? void 0 : params[wildcardNoBraces];
20
+ return sub || `${wildcardNoBraces}${utils.randomInt(1, 9)}`;
21
+ });
49
22
  }
50
- return request.post({
51
- callback: this._requestCallBack,
52
- baseUrl: this.url,
53
- uri: "",
54
- body: { data: data },
55
- json: true,
56
- headers: headers,
57
- });
58
- };
59
- LocalFunction.prototype._constructAuth = function (auth, authType) {
60
- if (_.get(auth, "admin") || _.get(auth, "variable")) {
61
- return auth;
23
+ constructCallableFunc(data, opts) {
24
+ opts = opts || {};
25
+ const headers = {};
26
+ if (opts.instanceIdToken) {
27
+ headers["Firebase-Instance-ID-Token"] = opts.instanceIdToken;
28
+ }
29
+ return request.post({
30
+ callback: (...args) => this.requestCallBack(...args),
31
+ baseUrl: this.url,
32
+ uri: "",
33
+ body: { data },
34
+ json: true,
35
+ headers: headers,
36
+ });
62
37
  }
63
- if (typeof authType !== "undefined") {
64
- switch (authType) {
65
- case "USER":
66
- return {
67
- variable: {
68
- uid: _.get(auth, "uid", ""),
69
- token: _.get(auth, "token", {}),
70
- },
71
- };
72
- case "ADMIN":
73
- if (_.get(auth, "uid") || _.get(auth, "token")) {
74
- throw new Error("authType and auth are incompatible.");
75
- }
76
- return { admin: true };
77
- case "UNAUTHENTICATED":
78
- if (_.get(auth, "uid") || _.get(auth, "token")) {
79
- throw new Error("authType and auth are incompatible.");
80
- }
81
- return { admin: false };
82
- default:
83
- throw new Error("Unrecognized authType, valid values are: " + "ADMIN, USER, and UNAUTHENTICATED");
38
+ constructAuth(auth, authType) {
39
+ var _a, _b, _c;
40
+ if ((auth === null || auth === void 0 ? void 0 : auth.admin) || (auth === null || auth === void 0 ? void 0 : auth.variable)) {
41
+ return {
42
+ admin: auth.admin || false,
43
+ variable: auth.variable,
44
+ };
84
45
  }
46
+ if (authType) {
47
+ switch (authType) {
48
+ case "USER":
49
+ return {
50
+ admin: false,
51
+ variable: {
52
+ uid: (_a = auth === null || auth === void 0 ? void 0 : auth.uid) !== null && _a !== void 0 ? _a : "",
53
+ token: (_b = auth === null || auth === void 0 ? void 0 : auth.token) !== null && _b !== void 0 ? _b : {},
54
+ },
55
+ };
56
+ case "ADMIN":
57
+ if ((auth === null || auth === void 0 ? void 0 : auth.uid) || (auth === null || auth === void 0 ? void 0 : auth.token)) {
58
+ throw new Error("authType and auth are incompatible.");
59
+ }
60
+ return { admin: true };
61
+ case "UNAUTHENTICATED":
62
+ if ((auth === null || auth === void 0 ? void 0 : auth.uid) || (auth === null || auth === void 0 ? void 0 : auth.token)) {
63
+ throw new Error("authType and auth are incompatible.");
64
+ }
65
+ return { admin: false };
66
+ default:
67
+ throw new Error("Unrecognized authType, valid values are: " + "ADMIN, USER, and UNAUTHENTICATED");
68
+ }
69
+ }
70
+ if (auth) {
71
+ return {
72
+ admin: false,
73
+ variable: {
74
+ uid: (_c = auth.uid) !== null && _c !== void 0 ? _c : "",
75
+ token: auth.token || {},
76
+ },
77
+ };
78
+ }
79
+ return { admin: true };
85
80
  }
86
- if (auth) {
81
+ makeFirestoreValue(input) {
82
+ if (typeof input === "undefined" ||
83
+ input === null ||
84
+ (typeof input === "object" && Object.keys(input).length === 0)) {
85
+ return {};
86
+ }
87
+ if (typeof input !== "object") {
88
+ throw new Error("Firestore data must be key-value pairs.");
89
+ }
90
+ const currentTime = new Date().toISOString();
87
91
  return {
88
- variable: {
89
- uid: auth.uid,
90
- token: auth.token || {},
91
- },
92
+ fields: (0, encodeFirestoreValue_1.encodeFirestoreValue)(input),
93
+ createTime: currentTime,
94
+ updateTime: currentTime,
92
95
  };
93
96
  }
94
- return { admin: true };
95
- };
96
- LocalFunction.prototype._makeFirestoreValue = function (input) {
97
- if (typeof input === "undefined" || _.isEmpty(input)) {
98
- return {};
99
- }
100
- if (typeof input !== "object") {
101
- throw new Error("Firestore data must be key-value pairs.");
102
- }
103
- var currentTime = new Date().toISOString();
104
- return {
105
- fields: encodeFirestoreValue(input),
106
- createTime: currentTime,
107
- updateTime: currentTime,
108
- };
109
- };
110
- LocalFunction.prototype._requestCallBack = function (err, response, body) {
111
- if (err) {
112
- return console.warn("\nERROR SENDING REQUEST: " + err);
113
- }
114
- var status = response ? response.statusCode + ", " : "";
115
- var bodyString = body;
116
- if (typeof body === "string") {
117
- try {
118
- bodyString = JSON.stringify(JSON.parse(bodyString), null, 2);
97
+ requestCallBack(err, response, body) {
98
+ if (err) {
99
+ return console.warn("\nERROR SENDING REQUEST: " + err);
119
100
  }
120
- catch (e) {
101
+ const status = response ? response.statusCode + ", " : "";
102
+ let bodyString = body;
103
+ if (typeof bodyString === "string") {
104
+ try {
105
+ bodyString = JSON.stringify(JSON.parse(bodyString), null, 2);
106
+ }
107
+ catch (e) {
108
+ }
109
+ }
110
+ else {
111
+ bodyString = JSON.stringify(body, null, 2);
121
112
  }
113
+ return console.log("\nRESPONSE RECEIVED FROM FUNCTION: " + status + bodyString);
122
114
  }
123
- else {
124
- bodyString = JSON.stringify(body, null, 2);
115
+ isDatabaseFn(eventTrigger) {
116
+ return utils.getFunctionsEventProvider(eventTrigger.eventType) === "Database";
125
117
  }
126
- return console.log("\nRESPONSE RECEIVED FROM FUNCTION: " + status + bodyString);
127
- };
128
- LocalFunction.prototype._call = function (data, opts) {
129
- opts = opts || {};
130
- var operationType;
131
- var dataPayload;
132
- if (this.httpsTrigger) {
133
- this.controller.call(this.name, data || {});
118
+ isFirestoreFunc(eventTrigger) {
119
+ return utils.getFunctionsEventProvider(eventTrigger.eventType) === "Firestore";
134
120
  }
135
- else if (this.eventTrigger) {
136
- if (this._isDatabaseFunc(this.eventTrigger)) {
137
- operationType = utils.last(this.eventTrigger.eventType.split("."));
138
- switch (operationType) {
139
- case "create":
140
- dataPayload = {
141
- data: null,
142
- delta: data,
143
- };
144
- break;
145
- case "delete":
146
- dataPayload = {
147
- data: data,
148
- delta: null,
149
- };
150
- break;
151
- default:
152
- dataPayload = {
153
- data: data.before,
154
- delta: data.after,
155
- };
121
+ triggerEvent(data, opts) {
122
+ opts = opts || {};
123
+ let operationType;
124
+ let dataPayload;
125
+ if (this.trigger.httpsTrigger) {
126
+ this.controller.call(this.trigger.name, data || {}, opts);
127
+ }
128
+ else if (this.trigger.eventTrigger) {
129
+ if (this.isDatabaseFn(this.trigger.eventTrigger)) {
130
+ operationType = utils.last(this.trigger.eventTrigger.eventType.split("."));
131
+ switch (operationType) {
132
+ case "create":
133
+ dataPayload = {
134
+ data: null,
135
+ delta: data,
136
+ };
137
+ break;
138
+ case "delete":
139
+ dataPayload = {
140
+ data: data,
141
+ delta: null,
142
+ };
143
+ break;
144
+ default:
145
+ dataPayload = {
146
+ data: data.before,
147
+ delta: data.after,
148
+ };
149
+ }
150
+ opts.resource = this.substituteParams(this.trigger.eventTrigger.resource, opts.params);
151
+ opts.auth = this.constructAuth(opts.auth, opts.authType);
152
+ this.controller.call(this.trigger.name, dataPayload, opts);
153
+ }
154
+ else if (this.isFirestoreFunc(this.trigger.eventTrigger)) {
155
+ operationType = utils.last(this.trigger.eventTrigger.eventType.split("."));
156
+ switch (operationType) {
157
+ case "create":
158
+ dataPayload = {
159
+ value: this.makeFirestoreValue(data),
160
+ oldValue: {},
161
+ };
162
+ break;
163
+ case "delete":
164
+ dataPayload = {
165
+ value: {},
166
+ oldValue: this.makeFirestoreValue(data),
167
+ };
168
+ break;
169
+ default:
170
+ dataPayload = {
171
+ value: this.makeFirestoreValue(data.after),
172
+ oldValue: this.makeFirestoreValue(data.before),
173
+ };
174
+ }
175
+ opts.resource = this.substituteParams(this.trigger.eventTrigger.resource, opts.params);
176
+ this.controller.call(this.trigger.name, dataPayload, opts);
177
+ }
178
+ else {
179
+ this.controller.call(this.trigger.name, data || {}, opts);
156
180
  }
157
- opts.resource = this._substituteParams(this.eventTrigger.resource, opts.params);
158
- opts.auth = this._constructAuth(opts.auth, opts.authType);
159
- this.controller.call(this.name, dataPayload, opts);
160
181
  }
161
- else if (this._isFirestoreFunc(this.eventTrigger)) {
162
- operationType = utils.last(this.eventTrigger.eventType.split("."));
163
- switch (operationType) {
164
- case "create":
165
- dataPayload = {
166
- value: this._makeFirestoreValue(data),
167
- oldValue: {},
168
- };
169
- break;
170
- case "delete":
171
- dataPayload = {
172
- value: {},
173
- oldValue: this._makeFirestoreValue(data),
174
- };
175
- break;
176
- default:
177
- dataPayload = {
178
- value: this._makeFirestoreValue(data.after),
179
- oldValue: this._makeFirestoreValue(data.before),
180
- };
182
+ return console.log("Successfully invoked function.");
183
+ }
184
+ makeFn() {
185
+ var _a;
186
+ if (this.trigger.httpsTrigger) {
187
+ const isCallable = !!((_a = this.trigger.labels) === null || _a === void 0 ? void 0 : _a["deployment-callable"]);
188
+ if (isCallable) {
189
+ return (data, opt) => this.constructCallableFunc(data, opt);
190
+ }
191
+ else {
192
+ return request.defaults({
193
+ callback: (...args) => this.requestCallBack(...args),
194
+ baseUrl: this.url,
195
+ uri: "",
196
+ });
181
197
  }
182
- opts.resource = this._substituteParams(this.eventTrigger.resource, opts.params);
183
- this.controller.call(this.name, dataPayload, opts);
184
198
  }
185
199
  else {
186
- this.controller.call(this.name, data || {}, opts);
200
+ return (data, opt) => this.triggerEvent(data, opt);
187
201
  }
188
202
  }
189
- return "Successfully invoked function.";
190
- };
191
- module.exports = LocalFunction;
203
+ }
204
+ exports.default = LocalFunction;
@@ -24,6 +24,14 @@ async function autoAuth(options, authScopes) {
24
24
  const client = getAuthClient({ scopes: authScopes, projectId: options.project });
25
25
  const token = await client.getAccessToken();
26
26
  token !== null ? apiv2.setAccessToken(token) : false;
27
+ let clientEmail;
28
+ try {
29
+ const credentials = await client.getCredentials();
30
+ clientEmail = credentials.client_email;
31
+ }
32
+ catch (e) {
33
+ logger_1.logger.debug(`Error getting account credentials.`);
34
+ }
27
35
  if (!options.isVSCE && (0, monospace_1.isMonospaceEnv)()) {
28
36
  await (0, monospace_1.selectProjectInMonospace)({
29
37
  projectRoot: options.config.projectDir,
@@ -31,6 +39,7 @@ async function autoAuth(options, authScopes) {
31
39
  isVSCE: options.isVSCE,
32
40
  });
33
41
  }
42
+ return clientEmail;
34
43
  }
35
44
  async function requireAuth(options) {
36
45
  api.setScopes([scopes.CLOUD_PLATFORM, scopes.FIREBASE_PLATFORM]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "12.4.2",
3
+ "version": "12.4.4",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -103,7 +103,7 @@
103
103
  "request": "^2.87.0",
104
104
  "retry": "^0.13.1",
105
105
  "rimraf": "^3.0.0",
106
- "semver": "^5.7.1",
106
+ "semver": "^7.5.2",
107
107
  "stream-chain": "^2.2.4",
108
108
  "stream-json": "^1.7.3",
109
109
  "strip-ansi": "^6.0.1",
@@ -12,7 +12,7 @@
12
12
  "license": "MIT",
13
13
  "dependencies": {
14
14
  "chalk": "^2.4.2",
15
- "npm": "^6.10.2",
15
+ "npm": "^9.8.0",
16
16
  "shelljs": "^0.8.3",
17
17
  "shx": "^0.3.2",
18
18
  "user-home": "^2.0.0"
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.command = void 0;
4
- const command_1 = require("../command");
5
- const repo_1 = require("../init/features/composer/repo");
6
- const projectUtils_1 = require("../projectUtils");
7
- const requireInteractive_1 = require("../requireInteractive");
8
- exports.command = new command_1.Command("internaltesting:frameworks:init")
9
- .description("connect github repo to cloud build")
10
- .before(requireInteractive_1.default)
11
- .action(async (options) => {
12
- const projectId = (0, projectUtils_1.needProjectId)(options);
13
- await (0, repo_1.linkGitHubRepository)(projectId, "us-central2", "stack0");
14
- });
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.listDatabaseInstances = void 0;
4
- const api_1 = require("../api");
5
- const apiv2_1 = require("../apiv2");
6
- const logger_1 = require("../logger");
7
- const utils = require("../utils");
8
- function _handleErrorResponse(response) {
9
- if (response.body && response.body.error) {
10
- return utils.reject(response.body.error, { code: 2 });
11
- }
12
- logger_1.logger.debug("[firedata] error:", response.status, response.body);
13
- return utils.reject("Unexpected error encountered with FireData.", {
14
- code: 2,
15
- });
16
- }
17
- async function listDatabaseInstances(projectNumber) {
18
- const client = new apiv2_1.Client({ urlPrefix: api_1.firedataOrigin, apiVersion: "v1" });
19
- const response = await client.get(`/projects/${projectNumber}/databases`, {
20
- resolveOnHTTPError: true,
21
- });
22
- if (response.status === 200) {
23
- return response.body.instance;
24
- }
25
- return _handleErrorResponse(response);
26
- }
27
- exports.listDatabaseInstances = listDatabaseInstances;