firebase-tools 13.0.1 → 13.0.2

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/api.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.githubApiOrigin = exports.githubOrigin = exports.frameworksOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin = exports.hostingApiOrigin = exports.firebaseStorageOrigin = exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.remoteConfigApiOrigin = exports.rtdbMetadataOrigin = exports.rtdbManagementOrigin = exports.realtimeOrigin = exports.extensionsTOSOrigin = exports.extensionsPublisherOrigin = exports.extensionsOrigin = exports.iamOrigin = exports.identityOrigin = exports.hostingOrigin = exports.googleOrigin = exports.pubsubOrigin = exports.cloudTasksOrigin = exports.cloudschedulerOrigin = exports.cloudbuildOrigin = exports.functionsDefaultRegion = exports.runOrigin = exports.functionsV2Origin = exports.functionsOrigin = exports.firestoreOrigin = exports.firestoreOriginOrEmulator = exports.firedataOrigin = exports.firebaseExtensionsRegistryOrigin = exports.firebaseApiOrigin = exports.eventarcOrigin = exports.dynamicLinksKey = exports.dynamicLinksOrigin = exports.deployOrigin = exports.consoleOrigin = exports.authOrigin = exports.appDistributionOrigin = exports.artifactRegistryDomain = exports.containerRegistryDomain = exports.cloudMonitoringOrigin = exports.cloudloggingOrigin = exports.cloudbillingOrigin = exports.clientSecret = exports.clientId = exports.authProxyOrigin = void 0;
3
+ exports.githubApiOrigin = exports.githubOrigin = exports.apphostingOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin = exports.hostingApiOrigin = exports.firebaseStorageOrigin = exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.remoteConfigApiOrigin = exports.rtdbMetadataOrigin = exports.rtdbManagementOrigin = exports.realtimeOrigin = exports.extensionsTOSOrigin = exports.extensionsPublisherOrigin = exports.extensionsOrigin = exports.iamOrigin = exports.identityOrigin = exports.hostingOrigin = exports.googleOrigin = exports.pubsubOrigin = exports.cloudTasksOrigin = exports.cloudschedulerOrigin = exports.cloudbuildOrigin = exports.functionsDefaultRegion = exports.runOrigin = exports.functionsV2Origin = exports.functionsOrigin = exports.firestoreOrigin = exports.firestoreOriginOrEmulator = exports.firedataOrigin = exports.firebaseExtensionsRegistryOrigin = exports.firebaseApiOrigin = exports.eventarcOrigin = exports.dynamicLinksKey = exports.dynamicLinksOrigin = exports.deployOrigin = exports.consoleOrigin = exports.authOrigin = exports.appDistributionOrigin = exports.artifactRegistryDomain = exports.containerRegistryDomain = exports.cloudMonitoringOrigin = exports.cloudloggingOrigin = exports.cloudbillingOrigin = exports.clientSecret = exports.clientId = exports.authProxyOrigin = void 0;
4
4
  exports.setScopes = exports.getScopes = exports.githubClientSecret = exports.githubClientId = exports.secretManagerOrigin = void 0;
5
5
  const constants_1 = require("./emulator/constants");
6
6
  const logger_1 = require("./logger");
@@ -59,7 +59,7 @@ exports.firebaseStorageOrigin = utils.envOverride("FIREBASE_FIREBASESTORAGE_URL"
59
59
  exports.hostingApiOrigin = utils.envOverride("FIREBASE_HOSTING_API_URL", "https://firebasehosting.googleapis.com");
60
60
  exports.cloudRunApiOrigin = utils.envOverride("CLOUD_RUN_API_URL", "https://run.googleapis.com");
61
61
  exports.serviceUsageOrigin = utils.envOverride("FIREBASE_SERVICE_USAGE_URL", "https://serviceusage.googleapis.com");
62
- exports.frameworksOrigin = utils.envOverride("FRAMEWORKS_URL", "https://placeholder.googleapis.com");
62
+ exports.apphostingOrigin = utils.envOverride("APPHOSTING_URL", "https://firebaseapphosting.googleapis.com");
63
63
  exports.githubOrigin = utils.envOverride("GITHUB_URL", "https://github.com");
64
64
  exports.githubApiOrigin = utils.envOverride("GITHUB_API_URL", "https://api.github.com");
65
65
  exports.secretManagerOrigin = utils.envOverride("CLOUD_SECRET_MANAGER_URL", "https://secretmanager.googleapis.com");
@@ -4,13 +4,14 @@ exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const projectUtils_1 = require("../projectUtils");
6
6
  const requireInteractive_1 = require("../requireInteractive");
7
- const frameworks_1 = require("../init/features/frameworks");
8
- const frameworks_2 = require("../gcp/frameworks");
9
- exports.command = new command_1.Command("backends:create")
7
+ const apphosting_1 = require("../init/features/apphosting");
8
+ const apphosting_2 = require("../gcp/apphosting");
9
+ exports.command = new command_1.Command("apphosting:backends:create")
10
10
  .description("Create a backend in a Firebase project")
11
- .before(frameworks_2.ensureApiEnabled)
11
+ .option("-l, --location <location>", "Specify the region of the backend", "")
12
+ .before(apphosting_2.ensureApiEnabled)
12
13
  .before(requireInteractive_1.default)
13
14
  .action(async (options) => {
14
15
  const projectId = (0, projectUtils_1.needProjectId)(options);
15
- await (0, frameworks_1.doSetup)(options, projectId);
16
+ await (0, apphosting_1.doSetup)(options, projectId);
16
17
  });
@@ -4,12 +4,11 @@ exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const projectUtils_1 = require("../projectUtils");
6
6
  const error_1 = require("../error");
7
- const gcp = require("../gcp/frameworks");
8
7
  const prompt_1 = require("../prompt");
9
- const utils = require("../utils");
10
8
  const logger_1 = require("../logger");
11
- const constants_1 = require("../init/features/frameworks/constants");
12
- const frameworks_1 = require("../gcp/frameworks");
9
+ const constants_1 = require("../init/features/apphosting/constants");
10
+ const utils = require("../utils");
11
+ const apphosting = require("../gcp/apphosting");
13
12
  const Table = require("cli-table");
14
13
  const COLUMN_LENGTH = 20;
15
14
  const TABLE_HEAD = [
@@ -20,12 +19,12 @@ const TABLE_HEAD = [
20
19
  "Created Date",
21
20
  "Updated Date",
22
21
  ];
23
- exports.command = new command_1.Command("backends:delete")
22
+ exports.command = new command_1.Command("apphosting:backends:delete")
24
23
  .description("Delete a backend from a Firebase project")
25
24
  .option("-l, --location <location>", "App Backend location", "")
26
25
  .option("-s, --backend <backend>", "Backend Id", "")
27
26
  .withForce()
28
- .before(frameworks_1.ensureApiEnabled)
27
+ .before(apphosting.ensureApiEnabled)
29
28
  .action(async (options) => {
30
29
  const projectId = (0, projectUtils_1.needProjectId)(options);
31
30
  let location = options.location;
@@ -34,12 +33,13 @@ exports.command = new command_1.Command("backends:delete")
34
33
  throw new error_1.FirebaseError("Backend id can't be empty.");
35
34
  }
36
35
  if (!location) {
36
+ const allowedLocations = (await apphosting.listLocations(projectId)).map((loc) => loc.locationId);
37
37
  location = await (0, prompt_1.promptOnce)({
38
38
  name: "region",
39
39
  type: "list",
40
40
  default: constants_1.DEFAULT_REGION,
41
41
  message: "Please select the region of the backend you'd like to delete:",
42
- choices: constants_1.ALLOWED_REGIONS,
42
+ choices: allowedLocations,
43
43
  });
44
44
  }
45
45
  const table = new Table({
@@ -49,7 +49,7 @@ exports.command = new command_1.Command("backends:delete")
49
49
  table.colWidths = COLUMN_LENGTH;
50
50
  let backend;
51
51
  try {
52
- backend = await gcp.getBackend(projectId, location, backendId);
52
+ backend = await apphosting.getBackend(projectId, location, backendId);
53
53
  populateTable(backend, table);
54
54
  }
55
55
  catch (err) {
@@ -69,7 +69,7 @@ exports.command = new command_1.Command("backends:delete")
69
69
  throw new error_1.FirebaseError("Deletion Aborted");
70
70
  }
71
71
  try {
72
- await gcp.deleteBackend(projectId, location, backendId);
72
+ await apphosting.deleteBackend(projectId, location, backendId);
73
73
  utils.logSuccess(`Successfully deleted the backend: ${backendId}`);
74
74
  }
75
75
  catch (err) {
@@ -3,24 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const projectUtils_1 = require("../projectUtils");
6
- const gcp = require("../gcp/frameworks");
7
6
  const error_1 = require("../error");
8
7
  const logger_1 = require("../logger");
9
- const frameworks_1 = require("../gcp/frameworks");
8
+ const utils_1 = require("../utils");
9
+ const apphosting = require("../gcp/apphosting");
10
10
  const Table = require("cli-table");
11
11
  const COLUMN_LENGTH = 20;
12
- const TABLE_HEAD = [
13
- "Backend Id",
14
- "Repository Name",
15
- "Location",
16
- "URL",
17
- "Created Date",
18
- "Updated Date",
19
- ];
20
- exports.command = new command_1.Command("backends:get <backendId>")
12
+ const TABLE_HEAD = ["Backend Id", "Repository", "Location", "URL", "Created Date", "Updated Date"];
13
+ exports.command = new command_1.Command("apphosting:backends:get <backendId>")
21
14
  .description("Get backend details of a Firebase project")
22
15
  .option("-l, --location <location>", "App Backend location", "-")
23
- .before(frameworks_1.ensureApiEnabled)
16
+ .before(apphosting.ensureApiEnabled)
24
17
  .action(async (backendId, options) => {
25
18
  const projectId = (0, projectUtils_1.needProjectId)(options);
26
19
  const location = options.location;
@@ -32,27 +25,26 @@ exports.command = new command_1.Command("backends:get <backendId>")
32
25
  table.colWidths = COLUMN_LENGTH;
33
26
  try {
34
27
  if (location !== "-") {
35
- const backendInRegion = await gcp.getBackend(projectId, location, backendId);
28
+ const backendInRegion = await apphosting.getBackend(projectId, location, backendId);
36
29
  backendsList.push(backendInRegion);
37
30
  populateTable(backendInRegion, table);
38
31
  }
39
32
  else {
40
- const allBackend = await gcp.listBackends(projectId, location);
41
- backendsList = allBackend.backends.filter((bkd) => bkd.name.split("/").pop() === backendId);
33
+ const resp = await apphosting.listBackends(projectId, "-");
34
+ const allBackends = resp.backends || [];
35
+ backendsList = allBackends.filter((bkd) => bkd.name.split("/").pop() === backendId);
42
36
  backendsList.forEach((bkd) => populateTable(bkd, table));
43
37
  }
44
- if (backendsList.length !== 0) {
45
- logger_1.logger.info(table.toString());
46
- }
47
- else {
48
- logger_1.logger.info();
49
- logger_1.logger.info(`There are no backends with id: ${backendId}`);
50
- }
51
38
  }
52
39
  catch (err) {
53
40
  throw new error_1.FirebaseError(`Failed to get backend: ${backendId}. Please check the parameters you have provided.`, { original: err });
54
41
  }
55
- return backendsList;
42
+ if (backendsList.length === 0) {
43
+ (0, utils_1.logWarning)(`Found no backend with id: ${backendId}`);
44
+ return;
45
+ }
46
+ logger_1.logger.info(table.toString());
47
+ return backendsList[0];
56
48
  });
57
49
  function populateTable(backend, table) {
58
50
  var _a;
@@ -3,18 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.command = void 0;
4
4
  const command_1 = require("../command");
5
5
  const projectUtils_1 = require("../projectUtils");
6
- const gcp = require("../gcp/frameworks");
7
6
  const error_1 = require("../error");
8
7
  const logger_1 = require("../logger");
9
- const colorette_1 = require("colorette");
10
- const frameworks_1 = require("../gcp/frameworks");
8
+ const apphosting = require("../gcp/apphosting");
11
9
  const Table = require("cli-table");
12
10
  const COLUMN_LENGTH = 20;
13
11
  const TABLE_HEAD = ["Backend Id", "Repository", "Location", "URL", "Created Date", "Updated Date"];
14
- exports.command = new command_1.Command("backends:list")
12
+ exports.command = new command_1.Command("apphosting:backends:list")
15
13
  .description("List backends of a Firebase project.")
16
14
  .option("-l, --location <location>", "App Backend location", "-")
17
- .before(frameworks_1.ensureApiEnabled)
15
+ .before(apphosting.ensureApiEnabled)
18
16
  .action(async (options) => {
19
17
  const projectId = (0, projectUtils_1.needProjectId)(options);
20
18
  const location = options.location;
@@ -25,12 +23,9 @@ exports.command = new command_1.Command("backends:list")
25
23
  table.colWidths = COLUMN_LENGTH;
26
24
  const backendsList = [];
27
25
  try {
28
- const backendsPerRegion = await gcp.listBackends(projectId, location);
29
- backendsList.push(...backendsPerRegion.backends);
26
+ const backendsPerRegion = await apphosting.listBackends(projectId, location);
27
+ backendsList.push(...(backendsPerRegion.backends || []));
30
28
  populateTable(backendsList, table);
31
- logger_1.logger.info();
32
- logger_1.logger.info(`Backends for project ${(0, colorette_1.bold)(projectId)}`);
33
- logger_1.logger.info();
34
29
  logger_1.logger.info(table.toString());
35
30
  }
36
31
  catch (err) {
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const apphosting = require("../gcp/apphosting");
5
+ const logger_1 = require("../logger");
6
+ const command_1 = require("../command");
7
+ const utils_1 = require("../utils");
8
+ const projectUtils_1 = require("../projectUtils");
9
+ exports.command = new command_1.Command("apphosting:builds:create <backendId>")
10
+ .description("Create a build for an App Hosting backend")
11
+ .option("-l, --location <location>", "Specify the region of the backend", "us-central1")
12
+ .option("-i, --id <buildId>", "Id of the build. If not present, autogenerate a random id", "")
13
+ .option("-b, --branch <branch>", "Repository branch to deploy. Defaults to 'main'", "main")
14
+ .before(apphosting.ensureApiEnabled)
15
+ .action(async (backendId, options) => {
16
+ const projectId = (0, projectUtils_1.needProjectId)(options);
17
+ const location = options.location;
18
+ const buildId = options.buildId || (0, utils_1.generateId)();
19
+ const branch = options.branch;
20
+ const op = await apphosting.createBuild(projectId, location, backendId, buildId, {
21
+ source: {
22
+ codebase: {
23
+ branch: "main",
24
+ },
25
+ },
26
+ });
27
+ logger_1.logger.info(`Started a build for backend ${backendId} on branch ${branch}.`);
28
+ logger_1.logger.info("Check status by running:");
29
+ logger_1.logger.info(`\tfirebase apphosting:builds:get ${backendId} ${buildId} --location ${location}`);
30
+ return op;
31
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const apphosting = require("../gcp/apphosting");
5
+ const logger_1 = require("../logger");
6
+ const command_1 = require("../command");
7
+ const projectUtils_1 = require("../projectUtils");
8
+ exports.command = new command_1.Command("apphosting:builds:get <backendId> <buildId>")
9
+ .description("Create a build for an App Hosting backend")
10
+ .option("-l, --location <location>", "Specify the region of the backend", "us-central1")
11
+ .before(apphosting.ensureApiEnabled)
12
+ .action(async (backendId, buildId, options) => {
13
+ const projectId = (0, projectUtils_1.needProjectId)(options);
14
+ const location = options.location;
15
+ const build = await apphosting.getBuild(projectId, location, backendId, buildId);
16
+ logger_1.logger.info(JSON.stringify(build, null, 2));
17
+ return build;
18
+ });
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const apphosting = require("../gcp/apphosting");
5
+ const logger_1 = require("../logger");
6
+ const command_1 = require("../command");
7
+ const projectUtils_1 = require("../projectUtils");
8
+ const utils_1 = require("../utils");
9
+ exports.command = new command_1.Command("apphosting:rollouts:create <backendId> <buildId>")
10
+ .description("Create a build for an App Hosting backend")
11
+ .option("-l, --location <location>", "Specify the region of the backend", "us-central1")
12
+ .option("-i, --id <rolloutId>", "Id of the rollout. If not present, autogenerate a random id", "")
13
+ .before(apphosting.ensureApiEnabled)
14
+ .action(async (backendId, buildId, options) => {
15
+ const projectId = (0, projectUtils_1.needProjectId)(options);
16
+ const location = options.location;
17
+ const rolloutId = options.buildId || (0, utils_1.generateId)();
18
+ const build = `projects/${projectId}/backends/${backendId}/builds/${buildId}`;
19
+ const op = await apphosting.createRollout(projectId, location, backendId, rolloutId, {
20
+ build,
21
+ });
22
+ logger_1.logger.info(`Started a rollout for backend ${backendId} with build ${buildId}.`);
23
+ logger_1.logger.info("Check status by running:");
24
+ logger_1.logger.info(`\tfirebase apphosting:rollouts:list --location ${location}`);
25
+ return op;
26
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = void 0;
4
+ const apphosting = require("../gcp/apphosting");
5
+ const logger_1 = require("../logger");
6
+ const command_1 = require("../command");
7
+ const projectUtils_1 = require("../projectUtils");
8
+ exports.command = new command_1.Command("apphosting:rollouts:list <backendId>")
9
+ .description("List rollouts of an App Hosting backend")
10
+ .option("-l, --location <location>", "Rgion of the rollouts. Defaults to listing rollouts from all regions", "-")
11
+ .before(apphosting.ensureApiEnabled)
12
+ .action(async (backendId, options) => {
13
+ const projectId = (0, projectUtils_1.needProjectId)(options);
14
+ const location = options.location;
15
+ const rollouts = await apphosting.listRollouts(projectId, location, backendId);
16
+ logger_1.logger.info(JSON.stringify(rollouts, null, 2));
17
+ return rollouts;
18
+ });
@@ -145,12 +145,18 @@ function load(client) {
145
145
  client.internaltesting.functions.discover = loadCommand("internaltesting-functions-discover");
146
146
  }
147
147
  if (experiments.isEnabled("internalframeworks")) {
148
- client.frameworks = {};
149
- client.frameworks.backends = {};
150
- client.frameworks.backends.list = loadCommand("frameworks-backends-list");
151
- client.frameworks.backends.create = loadCommand("frameworks-backends-create");
152
- client.frameworks.backends.get = loadCommand("frameworks-backends-get");
153
- client.frameworks.backends.delete = loadCommand("frameworks-backends-delete");
148
+ client.apphosting = {};
149
+ client.apphosting.backends = {};
150
+ client.apphosting.backends.list = loadCommand("apphosting-backends-list");
151
+ client.apphosting.backends.create = loadCommand("apphosting-backends-create");
152
+ client.apphosting.backends.get = loadCommand("apphosting-backends-get");
153
+ client.apphosting.backends.delete = loadCommand("apphosting-backends-delete");
154
+ client.apphosting.builds = {};
155
+ client.apphosting.builds.get = loadCommand("apphosting-builds-get");
156
+ client.apphosting.builds.create = loadCommand("apphosting-builds-create");
157
+ client.apphosting.rollouts = {};
158
+ client.apphosting.rollouts.create = loadCommand("apphosting-rollouts-create");
159
+ client.apphosting.rollouts.list = loadCommand("apphosting-rollouts-list");
154
160
  }
155
161
  client.login = loadCommand("login");
156
162
  client.login.add = loadCommand("login-add");
@@ -62,14 +62,14 @@ async function discover(dir, warn = true) {
62
62
  }
63
63
  exports.discover = discover;
64
64
  const BUILD_MEMO = new Map();
65
- function memoizeBuild(dir, build, deps, target) {
65
+ function memoizeBuild(dir, build, deps, target, context) {
66
66
  const key = [dir, ...deps];
67
67
  for (const existingKey of BUILD_MEMO.keys()) {
68
68
  if ((0, util_1.isDeepStrictEqual)(existingKey, key)) {
69
69
  return BUILD_MEMO.get(existingKey);
70
70
  }
71
71
  }
72
- const value = build(dir, target);
72
+ const value = build(dir, target, context);
73
73
  BUILD_MEMO.set(key, value);
74
74
  return value;
75
75
  }
@@ -197,6 +197,11 @@ async function prepareFrameworks(purpose, targetNames, context, options, emulato
197
197
  const frameworksBuildTarget = (0, utils_1.getFrameworksBuildTarget)(purpose, validBuildTargets);
198
198
  const useDevModeHandle = purpose !== "deploy" &&
199
199
  (await shouldUseDevModeHandle(frameworksBuildTarget, getProjectPath()));
200
+ const frameworkContext = {
201
+ projectId: project,
202
+ site: options.site,
203
+ hostingChannel: context === null || context === void 0 ? void 0 : context.hostingChannel,
204
+ };
200
205
  let codegenFunctionsDirectory;
201
206
  let baseUrl = "";
202
207
  const rewrites = [];
@@ -213,7 +218,7 @@ async function prepareFrameworks(purpose, targetNames, context, options, emulato
213
218
  }
214
219
  }
215
220
  else {
216
- const buildResult = await memoizeBuild(getProjectPath(), build, [firebaseDefaults, frameworksBuildTarget], frameworksBuildTarget);
221
+ const buildResult = await memoizeBuild(getProjectPath(), build, [firebaseDefaults, frameworksBuildTarget], frameworksBuildTarget, frameworkContext);
217
222
  const { wantsBackend = false, trailingSlash, i18n = false } = buildResult || {};
218
223
  if (buildResult) {
219
224
  baseUrl = (_d = buildResult.baseUrl) !== null && _d !== void 0 ? _d : baseUrl;
@@ -282,7 +287,7 @@ async function prepareFrameworks(purpose, targetNames, context, options, emulato
282
287
  else {
283
288
  await (0, fs_extra_1.mkdirp)(functionsDist);
284
289
  }
285
- const { packageJson, bootstrapScript, frameworksEntry = framework, dotEnv = {}, rewriteSource, } = await codegenFunctionsDirectory(getProjectPath(), functionsDist, frameworksBuildTarget);
290
+ const { packageJson, bootstrapScript, frameworksEntry = framework, dotEnv = {}, rewriteSource, } = await codegenFunctionsDirectory(getProjectPath(), functionsDist, frameworksBuildTarget, frameworkContext);
286
291
  const rewrite = {
287
292
  source: rewriteSource || path_1.posix.join(baseUrl, "**"),
288
293
  function: {
@@ -45,17 +45,24 @@ async function discover(dir) {
45
45
  return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir, PUBLIC_DIR), version };
46
46
  }
47
47
  exports.discover = discover;
48
- async function build(dir) {
48
+ async function build(dir, target, context) {
49
49
  var _a, _b;
50
50
  await (0, utils_1.warnIfCustomBuildScript)(dir, exports.name, DEFAULT_BUILD_SCRIPT);
51
51
  const reactVersion = getReactVersion(dir);
52
52
  if (reactVersion && (0, semver_1.gte)(reactVersion, "18.0.0")) {
53
53
  process.env.__NEXT_REACT_ROOT = "true";
54
54
  }
55
+ const env = Object.assign({}, process.env);
56
+ if ((context === null || context === void 0 ? void 0 : context.projectId) && (context === null || context === void 0 ? void 0 : context.site)) {
57
+ const deploymentDomain = await (0, api_1.getDeploymentDomain)(context.projectId, context.site, context.hostingChannel);
58
+ if (deploymentDomain) {
59
+ env["VERCEL_URL"] = deploymentDomain;
60
+ }
61
+ }
55
62
  const cli = (0, utils_1.getNodeModuleBin)("next", dir);
56
63
  const nextBuild = new Promise((resolve, reject) => {
57
64
  var _a, _b;
58
- const buildProcess = (0, cross_spawn_1.spawn)(cli, ["build"], { cwd: dir });
65
+ const buildProcess = (0, cross_spawn_1.spawn)(cli, ["build"], { cwd: dir, env });
59
66
  (_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", (data) => logger_1.logger.info(data.toString()));
60
67
  (_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on("data", (data) => logger_1.logger.info(data.toString()));
61
68
  buildProcess.on("error", (err) => {
@@ -304,7 +311,7 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
304
311
  }));
305
312
  }
306
313
  exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
307
- async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
314
+ async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context) {
308
315
  const { distDir } = await getConfig(sourceDir);
309
316
  const packageJson = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, "package.json"));
310
317
  if ((0, fs_1.existsSync)((0, path_1.join)(sourceDir, "next.config.js"))) {
@@ -354,9 +361,16 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
354
361
  if (await (0, utils_2.isUsingImageOptimization)(sourceDir, distDir)) {
355
362
  packageJson.dependencies["sharp"] = constants_1.SHARP_VERSION;
356
363
  }
364
+ const dotEnv = {};
365
+ if ((context === null || context === void 0 ? void 0 : context.projectId) && (context === null || context === void 0 ? void 0 : context.site)) {
366
+ const deploymentDomain = await (0, api_1.getDeploymentDomain)(context.projectId, context.site, context.hostingChannel);
367
+ if (deploymentDomain) {
368
+ dotEnv["VERCEL_URL"] = deploymentDomain;
369
+ }
370
+ }
357
371
  await (0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir));
358
372
  await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir), (0, path_1.join)(destDir, distDir));
359
- return { packageJson, frameworksEntry: "next.js" };
373
+ return { packageJson, frameworksEntry: "next.js", dotEnv };
360
374
  }
361
375
  exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
362
376
  async function getDevModeHandle(dir, _, hostingEmulatorInfo) {
@@ -162,7 +162,7 @@ exports.getNonStaticServerComponents = getNonStaticServerComponents;
162
162
  async function getHeadersFromMetaFiles(sourceDir, distDir, basePath, appPathRoutesManifest) {
163
163
  const headers = [];
164
164
  await Promise.all(Object.entries(appPathRoutesManifest).map(async ([key, source]) => {
165
- if ((0, path_1.basename)(key) !== "route")
165
+ if (!["route", "page"].includes((0, path_1.basename)(key)))
166
166
  return;
167
167
  const parts = source.split("/").filter((it) => !!it);
168
168
  const partsOrIndex = parts.length > 0 ? parts : ["index"];
@@ -6,7 +6,7 @@ const cross_spawn_1 = require("cross-spawn");
6
6
  const fs_1 = require("fs");
7
7
  const fs_extra_1 = require("fs-extra");
8
8
  const path_1 = require("path");
9
- const strip_ansi_1 = require("strip-ansi");
9
+ const stripAnsi = require("strip-ansi");
10
10
  const prompt_1 = require("../../prompt");
11
11
  const utils_1 = require("../utils");
12
12
  exports.name = "Vite";
@@ -90,7 +90,7 @@ async function getDevModeHandle(dir) {
90
90
  const serve = (0, cross_spawn_1.spawn)(cli, [], { cwd: dir });
91
91
  serve.stdout.on("data", (data) => {
92
92
  process.stdout.write(data);
93
- const dataWithoutAnsiCodes = (0, strip_ansi_1.default)(data.toString());
93
+ const dataWithoutAnsiCodes = stripAnsi(data.toString());
94
94
  const match = dataWithoutAnsiCodes.match(/(http:\/\/.+:\d+)/);
95
95
  if (match)
96
96
  resolve(match[1]);
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.API_VERSION = exports.API_HOST = void 0;
4
+ const proto = require("../gcp/proto");
5
+ const apiv2_1 = require("../apiv2");
6
+ const projectUtils_1 = require("../projectUtils");
7
+ const api_1 = require("../api");
8
+ const ensureApiEnabled_1 = require("../ensureApiEnabled");
9
+ exports.API_HOST = new URL(api_1.apphostingOrigin).host;
10
+ exports.API_VERSION = "v1alpha";
11
+ const client = new apiv2_1.Client({
12
+ urlPrefix: api_1.apphostingOrigin,
13
+ auth: true,
14
+ apiVersion: exports.API_VERSION,
15
+ });
16
+ async function createBackend(projectId, location, backendReqBoby, backendId) {
17
+ const res = await client.post(`projects/${projectId}/locations/${location}/backends`, backendReqBoby, { queryParams: { backendId } });
18
+ return res.body;
19
+ }
20
+ exports.createBackend = createBackend;
21
+ async function getBackend(projectId, location, backendId) {
22
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
23
+ const res = await client.get(name);
24
+ return res.body;
25
+ }
26
+ exports.getBackend = getBackend;
27
+ async function listBackends(projectId, location) {
28
+ const name = `projects/${projectId}/locations/${location}/backends`;
29
+ const res = await client.get(name);
30
+ return res.body;
31
+ }
32
+ exports.listBackends = listBackends;
33
+ async function deleteBackend(projectId, location, backendId) {
34
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
35
+ const res = await client.delete(name);
36
+ return res.body;
37
+ }
38
+ exports.deleteBackend = deleteBackend;
39
+ async function getBuild(projectId, location, backendId, buildId) {
40
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}/builds/${buildId}`;
41
+ const res = await client.get(name);
42
+ return res.body;
43
+ }
44
+ exports.getBuild = getBuild;
45
+ async function createBuild(projectId, location, backendId, buildId, buildInput) {
46
+ const res = await client.post(`projects/${projectId}/locations/${location}/backends/${backendId}/builds`, buildInput, { queryParams: { buildId } });
47
+ return res.body;
48
+ }
49
+ exports.createBuild = createBuild;
50
+ async function createRollout(projectId, location, backendId, rolloutId, rollout) {
51
+ const res = await client.post(`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`, rollout, { queryParams: { rolloutId } });
52
+ return res.body;
53
+ }
54
+ exports.createRollout = createRollout;
55
+ async function listRollouts(projectId, location, backendId) {
56
+ const res = await client.get(`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`);
57
+ return res.body.rollouts;
58
+ }
59
+ exports.listRollouts = listRollouts;
60
+ async function updateTraffic(projectId, location, backendId, traffic) {
61
+ const fieldMasks = proto.fieldMasks(traffic);
62
+ const queryParams = {
63
+ updateMask: fieldMasks.join(","),
64
+ };
65
+ const name = `projects/${projectId}/locations/${location}/backends/${backendId}/traffic`;
66
+ const res = await client.patch(name, Object.assign(Object.assign({}, traffic), { name }), {
67
+ queryParams,
68
+ });
69
+ return res.body;
70
+ }
71
+ exports.updateTraffic = updateTraffic;
72
+ async function listLocations(projectId) {
73
+ let pageToken;
74
+ let locations = [];
75
+ do {
76
+ const response = await client.get(`projects/${projectId}/locations`);
77
+ if (response.body.locations && response.body.locations.length > 0) {
78
+ locations = locations.concat(response.body.locations);
79
+ }
80
+ pageToken = response.body.nextPageToken;
81
+ } while (pageToken);
82
+ return locations;
83
+ }
84
+ exports.listLocations = listLocations;
85
+ async function ensureApiEnabled(options) {
86
+ const projectId = (0, projectUtils_1.needProjectId)(options);
87
+ return await (0, ensureApiEnabled_1.ensure)(projectId, exports.API_HOST, "frameworks", true);
88
+ }
89
+ exports.ensureApiEnabled = ensureApiEnabled;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAllSiteDomains = exports.getSiteDomains = exports.cleanAuthState = exports.getCleanDomains = exports.removeAuthDomain = exports.addAuthDomains = exports.deleteSite = exports.updateSite = exports.createSite = exports.getSite = exports.listSites = exports.createRelease = exports.cloneVersion = exports.listVersions = exports.updateVersion = exports.createVersion = exports.deleteChannel = exports.updateChannelTtl = exports.createChannel = exports.listChannels = exports.getChannel = exports.normalizeName = exports.SiteType = void 0;
3
+ exports.getDeploymentDomain = exports.getAllSiteDomains = exports.getSiteDomains = exports.cleanAuthState = exports.getCleanDomains = exports.removeAuthDomain = exports.addAuthDomains = exports.deleteSite = exports.updateSite = exports.createSite = exports.getSite = exports.listSites = exports.createRelease = exports.cloneVersion = exports.listVersions = exports.updateVersion = exports.createVersion = exports.deleteChannel = exports.updateChannelTtl = exports.createChannel = exports.listChannels = exports.getChannel = exports.normalizeName = exports.SiteType = void 0;
4
4
  const error_1 = require("../error");
5
5
  const api_1 = require("../api");
6
6
  const apiv2_1 = require("../apiv2");
@@ -8,6 +8,7 @@ const operationPoller = require("../operation-poller");
8
8
  const expireUtils_1 = require("../hosting/expireUtils");
9
9
  const auth_1 = require("../gcp/auth");
10
10
  const proto = require("../gcp/proto");
11
+ const utils_1 = require("../utils");
11
12
  const ONE_WEEK_MS = 604800000;
12
13
  var ReleaseType;
13
14
  (function (ReleaseType) {
@@ -170,6 +171,7 @@ async function getSite(project, site) {
170
171
  if (e instanceof error_1.FirebaseError && e.status === 404) {
171
172
  throw new error_1.FirebaseError(`could not find site "${site}" for project "${project}"`, {
172
173
  original: e,
174
+ status: e.status,
173
175
  });
174
176
  }
175
177
  throw e;
@@ -287,3 +289,19 @@ async function getAllSiteDomains(projectId, siteId) {
287
289
  return Array.from(allSiteDomains);
288
290
  }
289
291
  exports.getAllSiteDomains = getAllSiteDomains;
292
+ async function getDeploymentDomain(projectId, siteId, hostingChannel) {
293
+ if (hostingChannel) {
294
+ const channel = await getChannel(projectId, siteId, hostingChannel);
295
+ return channel && (0, utils_1.getHostnameFromUrl)(channel === null || channel === void 0 ? void 0 : channel.url);
296
+ }
297
+ const site = await getSite(projectId, siteId).catch((e) => {
298
+ if (e instanceof error_1.FirebaseError &&
299
+ e.original instanceof error_1.FirebaseError &&
300
+ e.original.status === 404) {
301
+ return null;
302
+ }
303
+ throw e;
304
+ });
305
+ return site && (0, utils_1.getHostnameFromUrl)(site === null || site === void 0 ? void 0 : site.defaultUrl);
306
+ }
307
+ exports.getDeploymentDomain = getDeploymentDomain;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ALLOWED_DEPLOY_METHODS = exports.DEFAULT_DEPLOY_METHOD = exports.ALLOWED_REGIONS = exports.DEFAULT_REGION = void 0;
3
+ exports.ALLOWED_DEPLOY_METHODS = exports.DEFAULT_DEPLOY_METHOD = exports.DEFAULT_REGION = void 0;
4
4
  exports.DEFAULT_REGION = "us-central1";
5
- exports.ALLOWED_REGIONS = [{ name: "us-central1 (Iowa)", value: "us-central1" }];
6
5
  exports.DEFAULT_DEPLOY_METHOD = "github";
7
6
  exports.ALLOWED_DEPLOY_METHODS = [{ name: "Deploy using github", value: "github" }];
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.onboardRollout = exports.createBackend = exports.onboardBackend = exports.doSetup = void 0;
4
+ const clc = require("colorette");
5
+ const repo = require("./repo");
6
+ const poller = require("../../../operation-poller");
7
+ const apphosting = require("../../../gcp/apphosting");
8
+ const utils_1 = require("../../../utils");
9
+ const api_1 = require("../../../api");
10
+ const apphosting_1 = require("../../../gcp/apphosting");
11
+ const error_1 = require("../../../error");
12
+ const prompt_1 = require("../../../prompt");
13
+ const constants_1 = require("./constants");
14
+ const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
15
+ const apphostingPollerOptions = {
16
+ apiOrigin: api_1.apphostingOrigin,
17
+ apiVersion: apphosting_1.API_VERSION,
18
+ masterTimeout: 25 * 60 * 1000,
19
+ maxBackoff: 10000,
20
+ };
21
+ async function doSetup(setup, projectId) {
22
+ await Promise.all([
23
+ (0, ensureApiEnabled_1.ensure)(projectId, "cloudbuild.googleapis.com", "apphosting", true),
24
+ (0, ensureApiEnabled_1.ensure)(projectId, "secretmanager.googleapis.com", "apphosting", true),
25
+ (0, ensureApiEnabled_1.ensure)(projectId, "run.googleapis.com", "apphosting", true),
26
+ (0, ensureApiEnabled_1.ensure)(projectId, "artifactregistry.googleapis.com", "apphosting", true),
27
+ ]);
28
+ const allowedLocations = (await apphosting.listLocations(projectId)).map((loc) => loc.locationId);
29
+ if (setup.location) {
30
+ if (!allowedLocations.includes(setup.location)) {
31
+ throw new error_1.FirebaseError(`Invalid location ${setup.location}. Valid choices are ${allowedLocations.join(", ")}`);
32
+ }
33
+ }
34
+ (0, utils_1.logBullet)("First we need a few details to create your backend.");
35
+ const location = setup.location || (await promptLocation(projectId, allowedLocations));
36
+ (0, utils_1.logSuccess)(`Region set to ${location}.\n`);
37
+ let backendId;
38
+ while (true) {
39
+ backendId = await (0, prompt_1.promptOnce)({
40
+ name: "backendId",
41
+ type: "input",
42
+ default: "my-web-app",
43
+ message: "Create a name for your backend [1-30 characters]",
44
+ });
45
+ try {
46
+ await apphosting.getBackend(projectId, location, backendId);
47
+ }
48
+ catch (err) {
49
+ if (err.status === 404) {
50
+ break;
51
+ }
52
+ throw new error_1.FirebaseError(`Failed to check if backend with id ${backendId} already exists in ${location}`, { original: err });
53
+ }
54
+ (0, utils_1.logWarning)(`Backend with id ${backendId} already exists in ${location}`);
55
+ }
56
+ const backend = await onboardBackend(projectId, location, backendId);
57
+ const confirmRollout = await (0, prompt_1.promptOnce)({
58
+ type: "confirm",
59
+ name: "rollout",
60
+ default: true,
61
+ message: "Do you want to deploy now?",
62
+ });
63
+ if (!confirmRollout) {
64
+ (0, utils_1.logSuccess)(`Successfully created backend:\n\t${backend.name}`);
65
+ (0, utils_1.logSuccess)(`Your site will be deployed at:\n\thttps://${backend.uri}`);
66
+ return;
67
+ }
68
+ const branch = await (0, prompt_1.promptOnce)({
69
+ name: "branch",
70
+ type: "input",
71
+ default: "main",
72
+ message: "Which branch do you want to deploy?",
73
+ });
74
+ const { build } = await onboardRollout(projectId, location, backendId, {
75
+ source: {
76
+ codebase: {
77
+ branch,
78
+ },
79
+ },
80
+ });
81
+ if (build.state !== "READY") {
82
+ throw new error_1.FirebaseError(`Failed to build your app. Please inspect the build logs at ${build.buildLogsUri}.`, { children: [build.error] });
83
+ }
84
+ (0, utils_1.logSuccess)(`Successfully created backend:\n\t${backend.name}`);
85
+ (0, utils_1.logSuccess)(`Your site is now deployed at:\n\thttps://${backend.uri}`);
86
+ (0, utils_1.logSuccess)(`View the rollout status by running:\n\tfirebase apphosting:backends:get ${backendId} --project ${projectId}`);
87
+ }
88
+ exports.doSetup = doSetup;
89
+ async function promptLocation(projectId, locations) {
90
+ return (await (0, prompt_1.promptOnce)({
91
+ name: "region",
92
+ type: "list",
93
+ default: constants_1.DEFAULT_REGION,
94
+ message: "Please select a region " +
95
+ `(${clc.yellow("info")}: Your region determines where your backend is located):\n`,
96
+ choices: locations.map((loc) => ({ value: loc })),
97
+ }));
98
+ }
99
+ function toBackend(cloudBuildConnRepo) {
100
+ return {
101
+ servingLocality: "GLOBAL_ACCESS",
102
+ codebase: {
103
+ repository: `${cloudBuildConnRepo.name}`,
104
+ rootDirectory: "/",
105
+ },
106
+ labels: {},
107
+ };
108
+ }
109
+ async function onboardBackend(projectId, location, backendId) {
110
+ const cloudBuildConnRepo = await repo.linkGitHubRepository(projectId, location);
111
+ const backendDetails = toBackend(cloudBuildConnRepo);
112
+ return await createBackend(projectId, location, backendDetails, backendId);
113
+ }
114
+ exports.onboardBackend = onboardBackend;
115
+ async function createBackend(projectId, location, backendReqBoby, backendId) {
116
+ const op = await apphosting.createBackend(projectId, location, backendReqBoby, backendId);
117
+ const backend = await poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-${backendId}`, operationResourceName: op.name }));
118
+ return backend;
119
+ }
120
+ exports.createBackend = createBackend;
121
+ async function onboardRollout(projectId, location, backendId, buildInput) {
122
+ (0, utils_1.logBullet)("Starting a new rollout... this may take a few minutes.");
123
+ const buildId = (0, utils_1.generateId)();
124
+ const buildOp = await apphosting.createBuild(projectId, location, backendId, buildId, buildInput);
125
+ const rolloutId = (0, utils_1.generateId)();
126
+ const rolloutOp = await apphosting.createRollout(projectId, location, backendId, rolloutId, {
127
+ build: `projects/${projectId}/locations/${location}/backends/${backendId}/builds/${buildId}`,
128
+ });
129
+ const rolloutPoll = poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-backend-${backendId}-rollout-${rolloutId}`, operationResourceName: rolloutOp.name }));
130
+ const buildPoll = poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-backend-${backendId}-build-${buildId}`, operationResourceName: buildOp.name }));
131
+ const [rollout, build] = await Promise.all([rolloutPoll, buildPoll]);
132
+ (0, utils_1.logSuccess)("Rollout completed.");
133
+ return { rollout, build };
134
+ }
135
+ exports.onboardRollout = onboardRollout;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.listFrameworksConnections = exports.getOrCreateRepository = exports.getOrCreateConnection = exports.createConnection = exports.linkGitHubRepository = exports.parseConnectionName = void 0;
3
+ exports.listAppHostingConnections = exports.getOrCreateRepository = exports.getOrCreateConnection = exports.createConnection = exports.linkGitHubRepository = exports.parseConnectionName = void 0;
4
4
  const clc = require("colorette");
5
5
  const gcb = require("../../../gcp/cloudbuild");
6
6
  const rm = require("../../../gcp/resourceManager");
@@ -10,8 +10,8 @@ const api_1 = require("../../../api");
10
10
  const error_1 = require("../../../error");
11
11
  const prompt_1 = require("../../../prompt");
12
12
  const getProjectNumber_1 = require("../../../getProjectNumber");
13
- const FRAMEWORKS_CONN_PATTERN = /.+\/frameworks-github-conn-.+$/;
14
- const FRAMEWORKS_OAUTH_CONN_NAME = "frameworks-github-oauth";
13
+ const APPHOSTING_CONN_PATTERN = /.+\/apphosting-github-conn-.+$/;
14
+ const APPHOSTING_OAUTH_CONN_NAME = "apphosting-github-oauth";
15
15
  const CONNECTION_NAME_REGEX = /^projects\/(?<projectId>[^\/]+)\/locations\/(?<location>[^\/]+)\/connections\/(?<id>[^\/]+)$/;
16
16
  function parseConnectionName(name) {
17
17
  const match = name.match(CONNECTION_NAME_REGEX);
@@ -45,18 +45,18 @@ function generateRepositoryId(remoteUri) {
45
45
  }
46
46
  function generateConnectionId() {
47
47
  const randomHash = Math.random().toString(36).slice(6);
48
- return `frameworks-github-conn-${randomHash}`;
48
+ return `apphosting-github-conn-${randomHash}`;
49
49
  }
50
50
  async function linkGitHubRepository(projectId, location) {
51
51
  var _a, _b, _c;
52
52
  utils.logBullet(clc.bold(`${clc.yellow("===")} Set up a GitHub connection`));
53
- const existingConns = await listFrameworksConnections(projectId);
53
+ const existingConns = await listAppHostingConnections(projectId);
54
54
  if (existingConns.length < 1) {
55
55
  const grantSuccess = await promptSecretManagerAdminGrant(projectId);
56
56
  if (!grantSuccess) {
57
57
  throw new error_1.FirebaseError("Insufficient IAM permissions to create a new connection to GitHub");
58
58
  }
59
- let oauthConn = await getOrCreateConnection(projectId, location, FRAMEWORKS_OAUTH_CONN_NAME);
59
+ let oauthConn = await getOrCreateConnection(projectId, location, APPHOSTING_OAUTH_CONN_NAME);
60
60
  while (oauthConn.installationState.stage === "PENDING_USER_OAUTH") {
61
61
  oauthConn = await promptConnectionAuth(oauthConn);
62
62
  }
@@ -70,14 +70,14 @@ async function linkGitHubRepository(projectId, location) {
70
70
  }
71
71
  existingConns.push(refreshedConn);
72
72
  }
73
- let { remoteUri, connection } = await promptRepositoryUri(projectId, location, existingConns);
73
+ let { remoteUri, connection } = await promptRepositoryUri(projectId, existingConns);
74
74
  while (remoteUri === "") {
75
75
  await utils.openInBrowser("https://github.com/apps/google-cloud-build/installations/new");
76
76
  await (0, prompt_1.promptOnce)({
77
77
  type: "input",
78
78
  message: "Press ENTER once you have finished configuring your installation's access settings.",
79
79
  });
80
- const selection = await promptRepositoryUri(projectId, location, existingConns);
80
+ const selection = await promptRepositoryUri(projectId, existingConns);
81
81
  remoteUri = selection.remoteUri;
82
82
  connection = selection.connection;
83
83
  }
@@ -92,10 +92,10 @@ async function linkGitHubRepository(projectId, location) {
92
92
  return repo;
93
93
  }
94
94
  exports.linkGitHubRepository = linkGitHubRepository;
95
- async function promptRepositoryUri(projectId, location, connections) {
95
+ async function promptRepositoryUri(projectId, connections) {
96
96
  const remoteUriToConnection = {};
97
97
  for (const conn of connections) {
98
- const { id } = parseConnectionName(conn.name);
98
+ const { location, id } = parseConnectionName(conn.name);
99
99
  const resp = await gcb.fetchLinkableRepositories(projectId, location, id);
100
100
  if (resp.repositories && resp.repositories.length > 0) {
101
101
  for (const repo of resp.repositories) {
@@ -210,10 +210,10 @@ async function getOrCreateRepository(projectId, location, connectionId, remoteUr
210
210
  return repo;
211
211
  }
212
212
  exports.getOrCreateRepository = getOrCreateRepository;
213
- async function listFrameworksConnections(projectId) {
213
+ async function listAppHostingConnections(projectId) {
214
214
  const conns = await gcb.listConnections(projectId, "-");
215
- return conns.filter((conn) => FRAMEWORKS_CONN_PATTERN.test(conn.name) &&
215
+ return conns.filter((conn) => APPHOSTING_CONN_PATTERN.test(conn.name) &&
216
216
  conn.installationState.stage === "COMPLETE" &&
217
217
  !conn.disabled);
218
218
  }
219
- exports.listFrameworksConnections = listFrameworksConnections;
219
+ exports.listAppHostingConnections = listAppHostingConnections;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.frameworks = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = exports.account = void 0;
3
+ exports.apphosting = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestore = exports.database = 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");
@@ -23,5 +23,5 @@ var remoteconfig_1 = require("./remoteconfig");
23
23
  Object.defineProperty(exports, "remoteconfig", { enumerable: true, get: function () { return remoteconfig_1.doSetup; } });
24
24
  var github_1 = require("./hosting/github");
25
25
  Object.defineProperty(exports, "hostingGithub", { enumerable: true, get: function () { return github_1.initGitHub; } });
26
- var frameworks_1 = require("./frameworks");
27
- Object.defineProperty(exports, "frameworks", { enumerable: true, get: function () { return frameworks_1.doSetup; } });
26
+ var apphosting_1 = require("./apphosting");
27
+ Object.defineProperty(exports, "apphosting", { enumerable: true, get: function () { return apphosting_1.doSetup; } });
package/lib/init/index.js CHANGED
@@ -6,7 +6,6 @@ const clc = require("colorette");
6
6
  const error_1 = require("../error");
7
7
  const logger_1 = require("../logger");
8
8
  const features = require("./features");
9
- const experiments_1 = require("../experiments");
10
9
  const featureFns = new Map([
11
10
  ["account", features.account],
12
11
  ["database", features.database],
@@ -20,9 +19,6 @@ const featureFns = new Map([
20
19
  ["remoteconfig", features.remoteconfig],
21
20
  ["hosting:github", features.hostingGithub],
22
21
  ]);
23
- if ((0, experiments_1.isEnabled)("internalframeworks")) {
24
- featureFns.set("internalframeworks", features.frameworks);
25
- }
26
22
  async function init(setup, config, options) {
27
23
  var _a;
28
24
  const nextFeature = (_a = setup.features) === null || _a === void 0 ? void 0 : _a.shift();
package/lib/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openInBrowserPopup = exports.openInBrowser = exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isVSCodeExtension = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
3
+ exports.generateId = exports.getHostnameFromUrl = exports.openInBrowserPopup = exports.openInBrowser = exports.connectableHostname = exports.randomInt = exports.debounce = exports.last = exports.cloneDeep = exports.groupBy = exports.assertIsStringOrUndefined = exports.assertIsNumber = exports.assertIsString = exports.thirtyDaysFromNow = exports.isRunningInWSL = exports.isVSCodeExtension = exports.isCloudEnvironment = exports.datetimeString = exports.createDestroyer = exports.promiseWithSpinner = exports.setupLoggers = exports.tryParse = exports.tryStringify = exports.promiseProps = exports.withTimeout = exports.promiseWhile = exports.promiseAllSettled = exports.getFunctionsEventProvider = exports.endpoint = exports.makeActiveProject = exports.streamToString = exports.stringToStream = exports.explainStdin = exports.allSettled = exports.reject = exports.logLabeledError = exports.logLabeledWarning = exports.logWarning = exports.logLabeledBullet = exports.logBullet = exports.logLabeledSuccess = exports.logSuccess = exports.addSubdomain = exports.addDatabaseNamespace = exports.getDatabaseViewDataUrl = exports.getDatabaseUrl = exports.envOverride = exports.getInheritedOption = exports.consoleUrl = exports.envOverrides = void 0;
4
4
  const fs = require("node:fs");
5
5
  const path = require("node:path");
6
6
  const _ = require("lodash");
@@ -515,3 +515,23 @@ async function openInBrowserPopup(url, buttonText) {
515
515
  };
516
516
  }
517
517
  exports.openInBrowserPopup = openInBrowserPopup;
518
+ function getHostnameFromUrl(url) {
519
+ try {
520
+ return new URL(url).hostname;
521
+ }
522
+ catch (e) {
523
+ return null;
524
+ }
525
+ }
526
+ exports.getHostnameFromUrl = getHostnameFromUrl;
527
+ function generateId(n = 6) {
528
+ const letters = "abcdefghijklmnopqrstuvwxyz";
529
+ const allChars = "01234567890-abcdefghijklmnopqrstuvwxyz";
530
+ let id = letters[Math.floor(Math.random() * letters.length)];
531
+ for (let i = 1; i < n; i++) {
532
+ const idx = Math.floor(Math.random() * allChars.length);
533
+ id += allChars[idx];
534
+ }
535
+ return id;
536
+ }
537
+ exports.generateId = generateId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-tools",
3
- "version": "13.0.1",
3
+ "version": "13.0.2",
4
4
  "description": "Command-Line Interface for Firebase",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ensureApiEnabled = exports.createBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.API_VERSION = exports.API_HOST = void 0;
4
- const apiv2_1 = require("../apiv2");
5
- const projectUtils_1 = require("../projectUtils");
6
- const api_1 = require("../api");
7
- const ensureApiEnabled_1 = require("../ensureApiEnabled");
8
- exports.API_HOST = new URL(api_1.frameworksOrigin).host;
9
- exports.API_VERSION = "v1alpha";
10
- const client = new apiv2_1.Client({
11
- urlPrefix: api_1.frameworksOrigin,
12
- auth: true,
13
- apiVersion: exports.API_VERSION,
14
- });
15
- async function createBackend(projectId, location, backendReqBoby, backendId) {
16
- const res = await client.post(`projects/${projectId}/locations/${location}/backends`, backendReqBoby, { queryParams: { backendId } });
17
- return res.body;
18
- }
19
- exports.createBackend = createBackend;
20
- async function getBackend(projectId, location, backendId) {
21
- const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
22
- const res = await client.get(name);
23
- return res.body;
24
- }
25
- exports.getBackend = getBackend;
26
- async function listBackends(projectId, location) {
27
- const name = `projects/${projectId}/locations/${location}/backends`;
28
- const res = await client.get(name);
29
- return res.body;
30
- }
31
- exports.listBackends = listBackends;
32
- async function deleteBackend(projectId, location, backendId) {
33
- const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
34
- const res = await client.delete(name);
35
- return res.body;
36
- }
37
- exports.deleteBackend = deleteBackend;
38
- async function createBuild(projectId, location, backendId, buildInput) {
39
- const buildId = buildInput.name;
40
- const res = await client.post(`projects/${projectId}/locations/${location}/backends/${backendId}/builds`, buildInput, { queryParams: { buildId } });
41
- return res.body;
42
- }
43
- exports.createBuild = createBuild;
44
- async function ensureApiEnabled(options) {
45
- const projectId = (0, projectUtils_1.needProjectId)(options);
46
- return await (0, ensureApiEnabled_1.ensure)(projectId, exports.API_HOST, "frameworks", true);
47
- }
48
- exports.ensureApiEnabled = ensureApiEnabled;
@@ -1,94 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBackend = exports.onboardBackend = exports.doSetup = void 0;
4
- const clc = require("colorette");
5
- const repo = require("./repo");
6
- const poller = require("../../../operation-poller");
7
- const gcp = require("../../../gcp/frameworks");
8
- const utils_1 = require("../../../utils");
9
- const api_1 = require("../../../api");
10
- const frameworks_1 = require("../../../gcp/frameworks");
11
- const error_1 = require("../../../error");
12
- const prompt_1 = require("../../../prompt");
13
- const constants_1 = require("./constants");
14
- const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
15
- const frameworksPollerOptions = {
16
- apiOrigin: api_1.frameworksOrigin,
17
- apiVersion: frameworks_1.API_VERSION,
18
- masterTimeout: 25 * 60 * 1000,
19
- maxBackoff: 10000,
20
- };
21
- async function doSetup(setup, projectId) {
22
- setup.frameworks = {};
23
- await Promise.all([
24
- (0, ensureApiEnabled_1.ensure)(projectId, "cloudbuild.googleapis.com", "frameworks", true),
25
- (0, ensureApiEnabled_1.ensure)(projectId, "secretmanager.googleapis.com", "frameworks", true),
26
- (0, ensureApiEnabled_1.ensure)(projectId, "run.googleapis.com", "frameworks", true),
27
- (0, ensureApiEnabled_1.ensure)(projectId, "artifactregistry.googleapis.com", "frameworks", true),
28
- ]);
29
- (0, utils_1.logBullet)("First we need a few details to create your backend.");
30
- const location = await (0, prompt_1.promptOnce)({
31
- name: "region",
32
- type: "list",
33
- default: constants_1.DEFAULT_REGION,
34
- message: "Please select a region " +
35
- `(${clc.yellow("info")}: Your region determines where your backend is located):\n`,
36
- choices: constants_1.ALLOWED_REGIONS,
37
- });
38
- (0, utils_1.logSuccess)(`Region set to ${location}.\n`);
39
- let backendId;
40
- while (true) {
41
- backendId = await (0, prompt_1.promptOnce)({
42
- name: "backendId",
43
- type: "input",
44
- default: "acme-inc-web",
45
- message: "Create a name for your backend [1-30 characters]",
46
- });
47
- try {
48
- await gcp.getBackend(projectId, location, backendId);
49
- }
50
- catch (err) {
51
- if (err.status === 404) {
52
- break;
53
- }
54
- throw new error_1.FirebaseError(`Failed to check if backend with id ${backendId} already exists in ${location}`, { original: err });
55
- }
56
- (0, utils_1.logWarning)(`Backend with id ${backendId} already exists in ${location}`);
57
- }
58
- const backend = await onboardBackend(projectId, location, backendId);
59
- if (backend) {
60
- (0, utils_1.logSuccess)(`Successfully created backend:\n\t${backend.name}`);
61
- (0, utils_1.logSuccess)(`Your site is being deployed at:\n\thttps://${backend.uri}`);
62
- (0, utils_1.logSuccess)(`View the rollout status by running:\n\tfirebase backends:get ${backendId} --project ${projectId}`);
63
- }
64
- }
65
- exports.doSetup = doSetup;
66
- function toBackend(cloudBuildConnRepo) {
67
- return {
68
- servingLocality: "GLOBAL_ACCESS",
69
- codebase: {
70
- repository: `${cloudBuildConnRepo.name}`,
71
- rootDirectory: "/",
72
- },
73
- labels: {},
74
- };
75
- }
76
- async function onboardBackend(projectId, location, backendId) {
77
- const cloudBuildConnRepo = await repo.linkGitHubRepository(projectId, location);
78
- const barnchName = await (0, prompt_1.promptOnce)({
79
- name: "branchName",
80
- type: "input",
81
- default: "main",
82
- message: "Which branch do you want to deploy?",
83
- });
84
- void barnchName;
85
- const backendDetails = toBackend(cloudBuildConnRepo);
86
- return await createBackend(projectId, location, backendDetails, backendId);
87
- }
88
- exports.onboardBackend = onboardBackend;
89
- async function createBackend(projectId, location, backendReqBoby, backendId) {
90
- const op = await gcp.createBackend(projectId, location, backendReqBoby, backendId);
91
- const backend = await poller.pollOperation(Object.assign(Object.assign({}, frameworksPollerOptions), { pollerName: `create-${projectId}-${location}-${backendId}`, operationResourceName: op.name }));
92
- return backend;
93
- }
94
- exports.createBackend = createBackend;