firebase-tools 13.5.2 → 13.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/lib/accountExporter.js +1 -1
  2. package/lib/accountImporter.js +1 -1
  3. package/lib/api.js +112 -58
  4. package/lib/apiv2.js +3 -1
  5. package/lib/appdistribution/client.js +4 -4
  6. package/lib/apphosting/config.js +31 -0
  7. package/lib/apphosting/githubConnections.js +261 -0
  8. package/lib/{init/features/apphosting → apphosting}/index.js +26 -22
  9. package/lib/{init/features/apphosting → apphosting}/repo.js +25 -13
  10. package/lib/apphosting/secrets/dialogs.js +169 -0
  11. package/lib/apphosting/secrets/index.js +98 -0
  12. package/lib/auth.js +17 -17
  13. package/lib/commands/apphosting-backends-create.js +4 -2
  14. package/lib/commands/apphosting-backends-delete.js +1 -1
  15. package/lib/commands/apphosting-secrets-describe.js +29 -0
  16. package/lib/commands/apphosting-secrets-grantaccess.js +45 -0
  17. package/lib/commands/apphosting-secrets-set.js +102 -0
  18. package/lib/commands/functions-secrets-access.js +2 -2
  19. package/lib/commands/functions-secrets-describe.js +14 -0
  20. package/lib/commands/functions-secrets-destroy.js +2 -2
  21. package/lib/commands/functions-secrets-get.js +3 -17
  22. package/lib/commands/functions-secrets-prune.js +2 -1
  23. package/lib/commands/functions-secrets-set.js +2 -2
  24. package/lib/commands/hosting-disable.js +1 -1
  25. package/lib/commands/index.js +5 -0
  26. package/lib/commands/open.js +1 -1
  27. package/lib/database/metadata.js +3 -3
  28. package/lib/defaultCredentials.js +2 -2
  29. package/lib/deploy/extensions/v2FunctionHelper.js +1 -1
  30. package/lib/deploy/functions/build.js +1 -1
  31. package/lib/deploy/functions/checkIam.js +3 -6
  32. package/lib/deploy/functions/containerCleaner.js +5 -15
  33. package/lib/deploy/functions/deploy.js +8 -2
  34. package/lib/deploy/functions/ensure.js +1 -1
  35. package/lib/deploy/functions/params.js +2 -2
  36. package/lib/deploy/functions/prepare.js +16 -7
  37. package/lib/deploy/functions/release/fabricator.js +8 -8
  38. package/lib/deploy/functions/runtimes/discovery/index.js +2 -2
  39. package/lib/deploy/functions/runtimes/index.js +6 -43
  40. package/lib/deploy/functions/runtimes/node/index.js +3 -2
  41. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +15 -34
  42. package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
  43. package/lib/deploy/functions/runtimes/python/index.js +11 -7
  44. package/lib/deploy/functions/runtimes/supported.js +135 -0
  45. package/lib/deploy/hosting/uploader.js +1 -1
  46. package/lib/deploy/index.js +1 -1
  47. package/lib/deploy/remoteconfig/functions.js +1 -1
  48. package/lib/emulator/adminSdkConfig.js +1 -1
  49. package/lib/emulator/controller.js +8 -1
  50. package/lib/emulator/downloadableEmulators.js +6 -6
  51. package/lib/emulator/functionsEmulator.js +2 -2
  52. package/lib/emulator/hub.js +5 -0
  53. package/lib/ensureApiEnabled.js +1 -1
  54. package/lib/extensions/emulator/specHelper.js +4 -3
  55. package/lib/extensions/extensionsApi.js +5 -5
  56. package/lib/extensions/extensionsHelper.js +4 -4
  57. package/lib/extensions/provisioningHelper.js +2 -2
  58. package/lib/extensions/publishHelpers.js +1 -1
  59. package/lib/extensions/publisherApi.js +3 -3
  60. package/lib/extensions/resolveSource.js +1 -1
  61. package/lib/extensions/secretsUtils.js +1 -1
  62. package/lib/extensions/tos.js +1 -1
  63. package/lib/fetchMOTD.js +1 -1
  64. package/lib/fetchWebSetup.js +2 -2
  65. package/lib/firestore/api-sort.js +17 -0
  66. package/lib/firestore/api.js +9 -2
  67. package/lib/firestore/checkDatabaseType.js +1 -1
  68. package/lib/firestore/delete.js +1 -1
  69. package/lib/firestore/pretty-print.js +11 -2
  70. package/lib/functional.js +2 -2
  71. package/lib/functions/secrets.js +42 -24
  72. package/lib/functionsConfig.js +1 -1
  73. package/lib/gcp/apphosting.js +17 -4
  74. package/lib/gcp/artifactregistry.js +1 -1
  75. package/lib/gcp/auth.js +1 -1
  76. package/lib/gcp/cloudbilling.js +1 -1
  77. package/lib/gcp/cloudbuild.js +8 -4
  78. package/lib/gcp/cloudfunctions.js +6 -6
  79. package/lib/gcp/cloudfunctionsv2.js +4 -4
  80. package/lib/gcp/cloudlogging.js +1 -1
  81. package/lib/gcp/cloudmonitoring.js +1 -1
  82. package/lib/gcp/cloudscheduler.js +3 -3
  83. package/lib/gcp/cloudtasks.js +1 -1
  84. package/lib/gcp/computeEngine.js +7 -0
  85. package/lib/gcp/devConnect.js +45 -22
  86. package/lib/gcp/eventarc.js +1 -1
  87. package/lib/gcp/firestore.js +2 -2
  88. package/lib/gcp/iam.js +11 -3
  89. package/lib/gcp/identityPlatform.js +1 -1
  90. package/lib/gcp/pubsub.js +1 -1
  91. package/lib/gcp/resourceManager.js +2 -1
  92. package/lib/gcp/rules.js +1 -1
  93. package/lib/gcp/run.js +1 -1
  94. package/lib/gcp/runtimeconfig.js +1 -1
  95. package/lib/gcp/secretManager.js +54 -14
  96. package/lib/gcp/serviceusage.js +21 -5
  97. package/lib/gcp/storage.js +12 -8
  98. package/lib/hosting/api.js +2 -2
  99. package/lib/hosting/cloudRunProxy.js +1 -1
  100. package/lib/init/features/database.js +1 -1
  101. package/lib/init/features/extensions/index.js +1 -1
  102. package/lib/init/features/functions/index.js +2 -2
  103. package/lib/init/features/functions/python.js +4 -3
  104. package/lib/init/features/hosting/github.js +4 -3
  105. package/lib/init/features/index.js +1 -1
  106. package/lib/management/apps.js +4 -4
  107. package/lib/management/database.js +1 -1
  108. package/lib/management/projects.js +4 -4
  109. package/lib/remoteconfig/get.js +1 -1
  110. package/lib/remoteconfig/rollback.js +1 -1
  111. package/lib/remoteconfig/versionslist.js +1 -1
  112. package/lib/shortenUrl.js +2 -2
  113. package/lib/utils.js +1 -1
  114. package/package.json +1 -1
  115. package/schema/firebase-config.json +12 -2
  116. /package/lib/{init/features/apphosting → apphosting}/constants.js +0 -0
@@ -8,7 +8,7 @@ const error_1 = require("./error");
8
8
  const api_1 = require("./api");
9
9
  const utils = require("./utils");
10
10
  const apiClient = new apiv2_1.Client({
11
- urlPrefix: api_1.googleOrigin,
11
+ urlPrefix: (0, api_1.googleOrigin)(),
12
12
  });
13
13
  const EXPORTED_JSON_KEYS = [
14
14
  "localId",
@@ -8,7 +8,7 @@ const logger_1 = require("./logger");
8
8
  const error_1 = require("./error");
9
9
  const utils = require("./utils");
10
10
  const apiClient = new apiv2_1.Client({
11
- urlPrefix: api_1.googleOrigin,
11
+ urlPrefix: (0, api_1.googleOrigin)(),
12
12
  });
13
13
  const ALLOWED_JSON_KEYS = [
14
14
  "localId",
package/lib/api.js CHANGED
@@ -1,73 +1,127 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- 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.developerConnectP4SAOrigin = exports.developerConnectOrigin = 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
- exports.setScopes = exports.getScopes = exports.githubClientSecret = exports.githubClientId = exports.computeOrigin = exports.secretManagerOrigin = exports.githubApiOrigin = exports.githubOrigin = void 0;
3
+ 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.developerConnectP4SAOrigin = exports.developerConnectOrigin = 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.consoleOrigin = exports.authOrigin = exports.appDistributionOrigin = exports.artifactRegistryDomain = exports.containerRegistryDomain = exports.cloudMonitoringOrigin = exports.cloudloggingOrigin = exports.cloudbillingOrigin = exports.clientSecret = exports.clientId = exports.authProxyOrigin = void 0;
4
+ exports.setScopes = exports.getScopes = exports.githubClientSecret = exports.githubClientId = exports.computeOrigin = exports.secretManagerOrigin = exports.githubApiOrigin = void 0;
5
5
  const constants_1 = require("./emulator/constants");
6
6
  const logger_1 = require("./logger");
7
7
  const scopes = require("./scopes");
8
8
  const utils = require("./utils");
9
9
  let commandScopes = new Set();
10
- exports.authProxyOrigin = utils.envOverride("FIREBASE_AUTHPROXY_URL", "https://auth.firebase.tools");
11
- exports.clientId = utils.envOverride("FIREBASE_CLIENT_ID", "563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com");
12
- exports.clientSecret = utils.envOverride("FIREBASE_CLIENT_SECRET", "j9iVZfS8kkCEFUPaAeJV0sAi");
13
- exports.cloudbillingOrigin = utils.envOverride("FIREBASE_CLOUDBILLING_URL", "https://cloudbilling.googleapis.com");
14
- exports.cloudloggingOrigin = utils.envOverride("FIREBASE_CLOUDLOGGING_URL", "https://logging.googleapis.com");
15
- exports.cloudMonitoringOrigin = utils.envOverride("CLOUD_MONITORING_URL", "https://monitoring.googleapis.com");
16
- exports.containerRegistryDomain = utils.envOverride("CONTAINER_REGISTRY_DOMAIN", "gcr.io");
17
- exports.artifactRegistryDomain = utils.envOverride("ARTIFACT_REGISTRY_DOMAIN", "https://artifactregistry.googleapis.com");
18
- exports.appDistributionOrigin = utils.envOverride("FIREBASE_APP_DISTRIBUTION_URL", "https://firebaseappdistribution.googleapis.com");
19
- exports.authOrigin = utils.envOverride("FIREBASE_AUTH_URL", "https://accounts.google.com");
20
- exports.consoleOrigin = utils.envOverride("FIREBASE_CONSOLE_URL", "https://console.firebase.google.com");
21
- exports.deployOrigin = utils.envOverride("FIREBASE_DEPLOY_URL", utils.envOverride("FIREBASE_UPLOAD_URL", "https://deploy.firebase.com"));
22
- exports.dynamicLinksOrigin = utils.envOverride("FIREBASE_DYNAMIC_LINKS_URL", "https://firebasedynamiclinks.googleapis.com");
23
- exports.dynamicLinksKey = utils.envOverride("FIREBASE_DYNAMIC_LINKS_KEY", "AIzaSyB6PtY5vuiSB8MNgt20mQffkOlunZnHYiQ");
24
- exports.eventarcOrigin = utils.envOverride("EVENTARC_URL", "https://eventarc.googleapis.com");
25
- exports.firebaseApiOrigin = utils.envOverride("FIREBASE_API_URL", "https://firebase.googleapis.com");
26
- exports.firebaseExtensionsRegistryOrigin = utils.envOverride("FIREBASE_EXT_REGISTRY_ORIGIN", "https://extensions-registry.firebaseapp.com");
27
- exports.firedataOrigin = utils.envOverride("FIREBASE_FIREDATA_URL", "https://mobilesdk-pa.googleapis.com");
28
- exports.firestoreOriginOrEmulator = utils.envOverride(constants_1.Constants.FIRESTORE_EMULATOR_HOST, utils.envOverride("FIRESTORE_URL", "https://firestore.googleapis.com"), (val) => {
10
+ const authProxyOrigin = () => utils.envOverride("FIREBASE_AUTHPROXY_URL", "https://auth.firebase.tools");
11
+ exports.authProxyOrigin = authProxyOrigin;
12
+ const clientId = () => utils.envOverride("FIREBASE_CLIENT_ID", "563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com");
13
+ exports.clientId = clientId;
14
+ const clientSecret = () => utils.envOverride("FIREBASE_CLIENT_SECRET", "j9iVZfS8kkCEFUPaAeJV0sAi");
15
+ exports.clientSecret = clientSecret;
16
+ const cloudbillingOrigin = () => utils.envOverride("FIREBASE_CLOUDBILLING_URL", "https://cloudbilling.googleapis.com");
17
+ exports.cloudbillingOrigin = cloudbillingOrigin;
18
+ const cloudloggingOrigin = () => utils.envOverride("FIREBASE_CLOUDLOGGING_URL", "https://logging.googleapis.com");
19
+ exports.cloudloggingOrigin = cloudloggingOrigin;
20
+ const cloudMonitoringOrigin = () => utils.envOverride("CLOUD_MONITORING_URL", "https://monitoring.googleapis.com");
21
+ exports.cloudMonitoringOrigin = cloudMonitoringOrigin;
22
+ const containerRegistryDomain = () => utils.envOverride("CONTAINER_REGISTRY_DOMAIN", "gcr.io");
23
+ exports.containerRegistryDomain = containerRegistryDomain;
24
+ const artifactRegistryDomain = () => utils.envOverride("ARTIFACT_REGISTRY_DOMAIN", "https://artifactregistry.googleapis.com");
25
+ exports.artifactRegistryDomain = artifactRegistryDomain;
26
+ const appDistributionOrigin = () => utils.envOverride("FIREBASE_APP_DISTRIBUTION_URL", "https://firebaseappdistribution.googleapis.com");
27
+ exports.appDistributionOrigin = appDistributionOrigin;
28
+ const authOrigin = () => utils.envOverride("FIREBASE_AUTH_URL", "https://accounts.google.com");
29
+ exports.authOrigin = authOrigin;
30
+ const consoleOrigin = () => utils.envOverride("FIREBASE_CONSOLE_URL", "https://console.firebase.google.com");
31
+ exports.consoleOrigin = consoleOrigin;
32
+ const dynamicLinksOrigin = () => utils.envOverride("FIREBASE_DYNAMIC_LINKS_URL", "https://firebasedynamiclinks.googleapis.com");
33
+ exports.dynamicLinksOrigin = dynamicLinksOrigin;
34
+ const dynamicLinksKey = () => utils.envOverride("FIREBASE_DYNAMIC_LINKS_KEY", "AIzaSyB6PtY5vuiSB8MNgt20mQffkOlunZnHYiQ");
35
+ exports.dynamicLinksKey = dynamicLinksKey;
36
+ const eventarcOrigin = () => utils.envOverride("EVENTARC_URL", "https://eventarc.googleapis.com");
37
+ exports.eventarcOrigin = eventarcOrigin;
38
+ const firebaseApiOrigin = () => utils.envOverride("FIREBASE_API_URL", "https://firebase.googleapis.com");
39
+ exports.firebaseApiOrigin = firebaseApiOrigin;
40
+ const firebaseExtensionsRegistryOrigin = () => utils.envOverride("FIREBASE_EXT_REGISTRY_ORIGIN", "https://extensions-registry.firebaseapp.com");
41
+ exports.firebaseExtensionsRegistryOrigin = firebaseExtensionsRegistryOrigin;
42
+ const firedataOrigin = () => utils.envOverride("FIREBASE_FIREDATA_URL", "https://mobilesdk-pa.googleapis.com");
43
+ exports.firedataOrigin = firedataOrigin;
44
+ const firestoreOriginOrEmulator = () => utils.envOverride(constants_1.Constants.FIRESTORE_EMULATOR_HOST, utils.envOverride("FIRESTORE_URL", "https://firestore.googleapis.com"), (val) => {
29
45
  if (val.startsWith("http")) {
30
46
  return val;
31
47
  }
32
48
  return `http://${val}`;
33
49
  });
34
- exports.firestoreOrigin = utils.envOverride("FIRESTORE_URL", "https://firestore.googleapis.com");
35
- exports.functionsOrigin = utils.envOverride("FIREBASE_FUNCTIONS_URL", "https://cloudfunctions.googleapis.com");
36
- exports.functionsV2Origin = utils.envOverride("FIREBASE_FUNCTIONS_V2_URL", "https://cloudfunctions.googleapis.com");
37
- exports.runOrigin = utils.envOverride("CLOUD_RUN_URL", "https://run.googleapis.com");
38
- exports.functionsDefaultRegion = utils.envOverride("FIREBASE_FUNCTIONS_DEFAULT_REGION", "us-central1");
39
- exports.cloudbuildOrigin = utils.envOverride("FIREBASE_CLOUDBUILD_URL", "https://cloudbuild.googleapis.com");
40
- exports.developerConnectOrigin = utils.envOverride("FIREBASE_DEVELOPERCONNECT_URL", "https://developerconnect.googleapis.com");
41
- exports.developerConnectP4SAOrigin = utils.envOverride("FIREBASE_DEVELOPERCONNECT_P4SA_URL", "gcp-sa-developerconnect.iam.gserviceaccount.com");
42
- exports.cloudschedulerOrigin = utils.envOverride("FIREBASE_CLOUDSCHEDULER_URL", "https://cloudscheduler.googleapis.com");
43
- exports.cloudTasksOrigin = utils.envOverride("FIREBASE_CLOUD_TAKS_URL", "https://cloudtasks.googleapis.com");
44
- exports.pubsubOrigin = utils.envOverride("FIREBASE_PUBSUB_URL", "https://pubsub.googleapis.com");
45
- exports.googleOrigin = utils.envOverride("FIREBASE_TOKEN_URL", utils.envOverride("FIREBASE_GOOGLE_URL", "https://www.googleapis.com"));
46
- exports.hostingOrigin = utils.envOverride("FIREBASE_HOSTING_URL", "https://web.app");
47
- exports.identityOrigin = utils.envOverride("FIREBASE_IDENTITY_URL", "https://identitytoolkit.googleapis.com");
48
- exports.iamOrigin = utils.envOverride("FIREBASE_IAM_URL", "https://iam.googleapis.com");
49
- exports.extensionsOrigin = utils.envOverride("FIREBASE_EXT_URL", "https://firebaseextensions.googleapis.com");
50
- exports.extensionsPublisherOrigin = utils.envOverride("FIREBASE_EXT_PUBLISHER_URL", "https://firebaseextensionspublisher.googleapis.com");
51
- exports.extensionsTOSOrigin = utils.envOverride("FIREBASE_EXT_TOS_URL", "https://firebaseextensionstos-pa.googleapis.com");
52
- exports.realtimeOrigin = utils.envOverride("FIREBASE_REALTIME_URL", "https://firebaseio.com");
53
- exports.rtdbManagementOrigin = utils.envOverride("FIREBASE_RTDB_MANAGEMENT_URL", "https://firebasedatabase.googleapis.com");
54
- exports.rtdbMetadataOrigin = utils.envOverride("FIREBASE_RTDB_METADATA_URL", "https://metadata-dot-firebase-prod.appspot.com");
55
- exports.remoteConfigApiOrigin = utils.envOverride("FIREBASE_REMOTE_CONFIG_URL", "https://firebaseremoteconfig.googleapis.com");
56
- exports.resourceManagerOrigin = utils.envOverride("FIREBASE_RESOURCEMANAGER_URL", "https://cloudresourcemanager.googleapis.com");
57
- exports.rulesOrigin = utils.envOverride("FIREBASE_RULES_URL", "https://firebaserules.googleapis.com");
58
- exports.runtimeconfigOrigin = utils.envOverride("FIREBASE_RUNTIMECONFIG_URL", "https://runtimeconfig.googleapis.com");
59
- exports.storageOrigin = utils.envOverride("FIREBASE_STORAGE_URL", "https://storage.googleapis.com");
60
- exports.firebaseStorageOrigin = utils.envOverride("FIREBASE_FIREBASESTORAGE_URL", "https://firebasestorage.googleapis.com");
61
- exports.hostingApiOrigin = utils.envOverride("FIREBASE_HOSTING_API_URL", "https://firebasehosting.googleapis.com");
62
- exports.cloudRunApiOrigin = utils.envOverride("CLOUD_RUN_API_URL", "https://run.googleapis.com");
63
- exports.serviceUsageOrigin = utils.envOverride("FIREBASE_SERVICE_USAGE_URL", "https://serviceusage.googleapis.com");
64
- exports.apphostingOrigin = utils.envOverride("APPHOSTING_URL", "https://firebaseapphosting.googleapis.com");
65
- exports.githubOrigin = utils.envOverride("GITHUB_URL", "https://github.com");
66
- exports.githubApiOrigin = utils.envOverride("GITHUB_API_URL", "https://api.github.com");
67
- exports.secretManagerOrigin = utils.envOverride("CLOUD_SECRET_MANAGER_URL", "https://secretmanager.googleapis.com");
68
- exports.computeOrigin = utils.envOverride("COMPUTE_URL", "https://compute.googleapis.com");
69
- exports.githubClientId = utils.envOverride("GITHUB_CLIENT_ID", "89cf50f02ac6aaed3484");
70
- exports.githubClientSecret = utils.envOverride("GITHUB_CLIENT_SECRET", "3330d14abc895d9a74d5f17cd7a00711fa2c5bf0");
50
+ exports.firestoreOriginOrEmulator = firestoreOriginOrEmulator;
51
+ const firestoreOrigin = () => utils.envOverride("FIRESTORE_URL", "https://firestore.googleapis.com");
52
+ exports.firestoreOrigin = firestoreOrigin;
53
+ const functionsOrigin = () => utils.envOverride("FIREBASE_FUNCTIONS_URL", "https://cloudfunctions.googleapis.com");
54
+ exports.functionsOrigin = functionsOrigin;
55
+ const functionsV2Origin = () => utils.envOverride("FIREBASE_FUNCTIONS_V2_URL", "https://cloudfunctions.googleapis.com");
56
+ exports.functionsV2Origin = functionsV2Origin;
57
+ const runOrigin = () => utils.envOverride("CLOUD_RUN_URL", "https://run.googleapis.com");
58
+ exports.runOrigin = runOrigin;
59
+ const functionsDefaultRegion = () => utils.envOverride("FIREBASE_FUNCTIONS_DEFAULT_REGION", "us-central1");
60
+ exports.functionsDefaultRegion = functionsDefaultRegion;
61
+ const cloudbuildOrigin = () => utils.envOverride("FIREBASE_CLOUDBUILD_URL", "https://cloudbuild.googleapis.com");
62
+ exports.cloudbuildOrigin = cloudbuildOrigin;
63
+ const developerConnectOrigin = () => utils.envOverride("FIREBASE_DEVELOPERCONNECT_URL", "https://developerconnect.googleapis.com");
64
+ exports.developerConnectOrigin = developerConnectOrigin;
65
+ const developerConnectP4SAOrigin = () => utils.envOverride("FIREBASE_DEVELOPERCONNECT_P4SA_URL", "gcp-sa-developerconnect.iam.gserviceaccount.com");
66
+ exports.developerConnectP4SAOrigin = developerConnectP4SAOrigin;
67
+ const cloudschedulerOrigin = () => utils.envOverride("FIREBASE_CLOUDSCHEDULER_URL", "https://cloudscheduler.googleapis.com");
68
+ exports.cloudschedulerOrigin = cloudschedulerOrigin;
69
+ const cloudTasksOrigin = () => utils.envOverride("FIREBASE_CLOUD_TAKS_URL", "https://cloudtasks.googleapis.com");
70
+ exports.cloudTasksOrigin = cloudTasksOrigin;
71
+ const pubsubOrigin = () => utils.envOverride("FIREBASE_PUBSUB_URL", "https://pubsub.googleapis.com");
72
+ exports.pubsubOrigin = pubsubOrigin;
73
+ const googleOrigin = () => utils.envOverride("FIREBASE_TOKEN_URL", utils.envOverride("FIREBASE_GOOGLE_URL", "https://www.googleapis.com"));
74
+ exports.googleOrigin = googleOrigin;
75
+ const hostingOrigin = () => utils.envOverride("FIREBASE_HOSTING_URL", "https://web.app");
76
+ exports.hostingOrigin = hostingOrigin;
77
+ const identityOrigin = () => utils.envOverride("FIREBASE_IDENTITY_URL", "https://identitytoolkit.googleapis.com");
78
+ exports.identityOrigin = identityOrigin;
79
+ const iamOrigin = () => utils.envOverride("FIREBASE_IAM_URL", "https://iam.googleapis.com");
80
+ exports.iamOrigin = iamOrigin;
81
+ const extensionsOrigin = () => utils.envOverride("FIREBASE_EXT_URL", "https://firebaseextensions.googleapis.com");
82
+ exports.extensionsOrigin = extensionsOrigin;
83
+ const extensionsPublisherOrigin = () => utils.envOverride("FIREBASE_EXT_PUBLISHER_URL", "https://firebaseextensionspublisher.googleapis.com");
84
+ exports.extensionsPublisherOrigin = extensionsPublisherOrigin;
85
+ const extensionsTOSOrigin = () => utils.envOverride("FIREBASE_EXT_TOS_URL", "https://firebaseextensionstos-pa.googleapis.com");
86
+ exports.extensionsTOSOrigin = extensionsTOSOrigin;
87
+ const realtimeOrigin = () => utils.envOverride("FIREBASE_REALTIME_URL", "https://firebaseio.com");
88
+ exports.realtimeOrigin = realtimeOrigin;
89
+ const rtdbManagementOrigin = () => utils.envOverride("FIREBASE_RTDB_MANAGEMENT_URL", "https://firebasedatabase.googleapis.com");
90
+ exports.rtdbManagementOrigin = rtdbManagementOrigin;
91
+ const rtdbMetadataOrigin = () => utils.envOverride("FIREBASE_RTDB_METADATA_URL", "https://metadata-dot-firebase-prod.appspot.com");
92
+ exports.rtdbMetadataOrigin = rtdbMetadataOrigin;
93
+ const remoteConfigApiOrigin = () => utils.envOverride("FIREBASE_REMOTE_CONFIG_URL", "https://firebaseremoteconfig.googleapis.com");
94
+ exports.remoteConfigApiOrigin = remoteConfigApiOrigin;
95
+ const resourceManagerOrigin = () => utils.envOverride("FIREBASE_RESOURCEMANAGER_URL", "https://cloudresourcemanager.googleapis.com");
96
+ exports.resourceManagerOrigin = resourceManagerOrigin;
97
+ const rulesOrigin = () => utils.envOverride("FIREBASE_RULES_URL", "https://firebaserules.googleapis.com");
98
+ exports.rulesOrigin = rulesOrigin;
99
+ const runtimeconfigOrigin = () => utils.envOverride("FIREBASE_RUNTIMECONFIG_URL", "https://runtimeconfig.googleapis.com");
100
+ exports.runtimeconfigOrigin = runtimeconfigOrigin;
101
+ const storageOrigin = () => utils.envOverride("FIREBASE_STORAGE_URL", "https://storage.googleapis.com");
102
+ exports.storageOrigin = storageOrigin;
103
+ const firebaseStorageOrigin = () => utils.envOverride("FIREBASE_FIREBASESTORAGE_URL", "https://firebasestorage.googleapis.com");
104
+ exports.firebaseStorageOrigin = firebaseStorageOrigin;
105
+ const hostingApiOrigin = () => utils.envOverride("FIREBASE_HOSTING_API_URL", "https://firebasehosting.googleapis.com");
106
+ exports.hostingApiOrigin = hostingApiOrigin;
107
+ const cloudRunApiOrigin = () => utils.envOverride("CLOUD_RUN_API_URL", "https://run.googleapis.com");
108
+ exports.cloudRunApiOrigin = cloudRunApiOrigin;
109
+ const serviceUsageOrigin = () => utils.envOverride("FIREBASE_SERVICE_USAGE_URL", "https://serviceusage.googleapis.com");
110
+ exports.serviceUsageOrigin = serviceUsageOrigin;
111
+ const apphostingOrigin = () => utils.envOverride("APPHOSTING_URL", "https://firebaseapphosting.googleapis.com");
112
+ exports.apphostingOrigin = apphostingOrigin;
113
+ const githubOrigin = () => utils.envOverride("GITHUB_URL", "https://github.com");
114
+ exports.githubOrigin = githubOrigin;
115
+ const githubApiOrigin = () => utils.envOverride("GITHUB_API_URL", "https://api.github.com");
116
+ exports.githubApiOrigin = githubApiOrigin;
117
+ const secretManagerOrigin = () => utils.envOverride("CLOUD_SECRET_MANAGER_URL", "https://secretmanager.googleapis.com");
118
+ exports.secretManagerOrigin = secretManagerOrigin;
119
+ const computeOrigin = () => utils.envOverride("COMPUTE_URL", "https://compute.googleapis.com");
120
+ exports.computeOrigin = computeOrigin;
121
+ const githubClientId = () => utils.envOverride("GITHUB_CLIENT_ID", "89cf50f02ac6aaed3484");
122
+ exports.githubClientId = githubClientId;
123
+ const githubClientSecret = () => utils.envOverride("GITHUB_CLIENT_SECRET", "3330d14abc895d9a74d5f17cd7a00711fa2c5bf0");
124
+ exports.githubClientSecret = githubClientSecret;
71
125
  function getScopes() {
72
126
  return Array.from(commandScopes);
73
127
  }
package/lib/apiv2.js CHANGED
@@ -135,7 +135,9 @@ class Client {
135
135
  reqOptions.headers.set("Content-Type", "application/json");
136
136
  }
137
137
  }
138
- if (GOOGLE_CLOUD_QUOTA_PROJECT && GOOGLE_CLOUD_QUOTA_PROJECT !== "") {
138
+ if (!reqOptions.ignoreQuotaProject &&
139
+ GOOGLE_CLOUD_QUOTA_PROJECT &&
140
+ GOOGLE_CLOUD_QUOTA_PROJECT !== "") {
139
141
  reqOptions.headers.set(GOOG_USER_PROJECT_HEADER, GOOGLE_CLOUD_QUOTA_PROJECT);
140
142
  }
141
143
  return reqOptions;
@@ -10,11 +10,11 @@ const types_1 = require("./types");
10
10
  class AppDistributionClient {
11
11
  constructor() {
12
12
  this.appDistroV1Client = new apiv2_1.Client({
13
- urlPrefix: api_1.appDistributionOrigin,
13
+ urlPrefix: (0, api_1.appDistributionOrigin)(),
14
14
  apiVersion: "v1",
15
15
  });
16
16
  this.appDistroV1AlphaClient = new apiv2_1.Client({
17
- urlPrefix: api_1.appDistributionOrigin,
17
+ urlPrefix: (0, api_1.appDistributionOrigin)(),
18
18
  apiVersion: "v1alpha",
19
19
  });
20
20
  }
@@ -23,7 +23,7 @@ class AppDistributionClient {
23
23
  return apiResponse.body;
24
24
  }
25
25
  async uploadRelease(appName, distribution) {
26
- const client = new apiv2_1.Client({ urlPrefix: api_1.appDistributionOrigin });
26
+ const client = new apiv2_1.Client({ urlPrefix: (0, api_1.appDistributionOrigin)() });
27
27
  const apiResponse = await client.request({
28
28
  method: "POST",
29
29
  path: `/upload/v1/${appName}/releases:upload`,
@@ -40,7 +40,7 @@ class AppDistributionClient {
40
40
  async pollUploadStatus(operationName) {
41
41
  return operationPoller.pollOperation({
42
42
  pollerName: "App Distribution Upload Poller",
43
- apiOrigin: api_1.appDistributionOrigin,
43
+ apiOrigin: (0, api_1.appDistributionOrigin)(),
44
44
  apiVersion: "v1",
45
45
  operationResourceName: operationName,
46
46
  masterTimeout: 5 * 60 * 1000,
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.store = exports.load = exports.yamlPath = void 0;
4
+ const path = require("path");
5
+ const fs_1 = require("fs");
6
+ const yaml = require("js-yaml");
7
+ const fs = require("../fsutils");
8
+ function yamlPath(cwd) {
9
+ let dir = cwd;
10
+ while (!fs.fileExistsSync(path.resolve(dir, "apphosting.yaml"))) {
11
+ if (fs.fileExistsSync(path.resolve(dir, "firebase.json"))) {
12
+ return null;
13
+ }
14
+ const parent = path.dirname(dir);
15
+ if (parent === dir) {
16
+ return null;
17
+ }
18
+ dir = parent;
19
+ }
20
+ return path.resolve(dir, "apphosting.yaml");
21
+ }
22
+ exports.yamlPath = yamlPath;
23
+ function load(yamlPath) {
24
+ const raw = fs.readFile(yamlPath);
25
+ return yaml.load(raw, yaml.DEFAULT_FULL_SCHEMA);
26
+ }
27
+ exports.load = load;
28
+ function store(yamlPath, config) {
29
+ (0, fs_1.writeFileSync)(yamlPath, yaml.dump(config));
30
+ }
31
+ exports.store = store;
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchAllRepositories = exports.listAppHostingConnections = exports.getOrCreateRepository = exports.getOrCreateConnection = exports.createConnection = exports.ensureSecretManagerAdminGrant = exports.getOrCreateOauthConnection = exports.linkGitHubRepository = exports.generateRepositoryId = exports.extractRepoSlugFromUri = exports.parseConnectionName = void 0;
4
+ const clc = require("colorette");
5
+ const devConnect = require("../gcp/devConnect");
6
+ const rm = require("../gcp/resourceManager");
7
+ const poller = require("../operation-poller");
8
+ const utils = require("../utils");
9
+ const error_1 = require("../error");
10
+ const prompt_1 = require("../prompt");
11
+ const getProjectNumber_1 = require("../getProjectNumber");
12
+ const api_1 = require("../api");
13
+ const fuzzy = require("fuzzy");
14
+ const inquirer = require("inquirer");
15
+ const APPHOSTING_CONN_PATTERN = /.+\/apphosting-github-conn-.+$/;
16
+ const APPHOSTING_OAUTH_CONN_NAME = "apphosting-github-oauth";
17
+ const CONNECTION_NAME_REGEX = /^projects\/(?<projectId>[^\/]+)\/locations\/(?<location>[^\/]+)\/connections\/(?<id>[^\/]+)$/;
18
+ function parseConnectionName(name) {
19
+ const match = CONNECTION_NAME_REGEX.exec(name);
20
+ if (!match || typeof match.groups === undefined) {
21
+ return;
22
+ }
23
+ const { projectId, location, id } = match.groups;
24
+ return {
25
+ projectId,
26
+ location,
27
+ id,
28
+ };
29
+ }
30
+ exports.parseConnectionName = parseConnectionName;
31
+ const devConnectPollerOptions = {
32
+ apiOrigin: (0, api_1.developerConnectOrigin)(),
33
+ apiVersion: "v1",
34
+ masterTimeout: 25 * 60 * 1000,
35
+ maxBackoff: 10000,
36
+ };
37
+ function extractRepoSlugFromUri(cloneUri) {
38
+ const match = /github.com\/(.+).git/.exec(cloneUri);
39
+ if (!match) {
40
+ return undefined;
41
+ }
42
+ return match[1];
43
+ }
44
+ exports.extractRepoSlugFromUri = extractRepoSlugFromUri;
45
+ function generateRepositoryId(remoteUri) {
46
+ var _a;
47
+ return (_a = extractRepoSlugFromUri(remoteUri)) === null || _a === void 0 ? void 0 : _a.replaceAll("/", "-");
48
+ }
49
+ exports.generateRepositoryId = generateRepositoryId;
50
+ function generateConnectionId() {
51
+ const randomHash = Math.random().toString(36).slice(6);
52
+ return `apphosting-github-conn-${randomHash}`;
53
+ }
54
+ const ADD_CONN_CHOICE = "@ADD_CONN";
55
+ async function linkGitHubRepository(projectId, location) {
56
+ var _a, _b;
57
+ utils.logBullet(clc.bold(`${clc.yellow("===")} Set up a GitHub connection`));
58
+ const oauthConn = await getOrCreateOauthConnection(projectId, location);
59
+ const existingConns = await listAppHostingConnections(projectId);
60
+ if (existingConns.length === 0) {
61
+ utils.logBullet("no connections exist");
62
+ existingConns.push(await createFullyInstalledConnection(projectId, location, generateConnectionId(), oauthConn));
63
+ }
64
+ let repoCloneUri;
65
+ let connection;
66
+ do {
67
+ if (repoCloneUri === ADD_CONN_CHOICE) {
68
+ existingConns.push(await createFullyInstalledConnection(projectId, location, generateConnectionId(), oauthConn));
69
+ }
70
+ const selection = await promptCloneUri(projectId, existingConns);
71
+ repoCloneUri = selection.cloneUri;
72
+ connection = selection.connection;
73
+ } while (repoCloneUri === ADD_CONN_CHOICE);
74
+ const { id: connectionId } = parseConnectionName(connection.name);
75
+ await getOrCreateConnection(projectId, location, connectionId, {
76
+ authorizerCredential: (_a = connection.githubConfig) === null || _a === void 0 ? void 0 : _a.authorizerCredential,
77
+ appInstallationId: (_b = connection.githubConfig) === null || _b === void 0 ? void 0 : _b.appInstallationId,
78
+ });
79
+ const repo = await getOrCreateRepository(projectId, location, connectionId, repoCloneUri);
80
+ utils.logSuccess(`Successfully linked GitHub repository at remote URI`);
81
+ utils.logSuccess(`\t${repo.cloneUri}`);
82
+ return repo;
83
+ }
84
+ exports.linkGitHubRepository = linkGitHubRepository;
85
+ async function createFullyInstalledConnection(projectId, location, connectionId, oauthConn) {
86
+ var _a, _b;
87
+ let conn = await createConnection(projectId, location, connectionId, {
88
+ appInstallationId: (_a = oauthConn.githubConfig) === null || _a === void 0 ? void 0 : _a.appInstallationId,
89
+ authorizerCredential: (_b = oauthConn.githubConfig) === null || _b === void 0 ? void 0 : _b.authorizerCredential,
90
+ });
91
+ while (conn.installationState.stage !== "COMPLETE") {
92
+ utils.logBullet("Install the Firebase GitHub app to enable access to GitHub repositories");
93
+ const targetUri = conn.installationState.actionUri.replace("install_v2", "direct_install_v2");
94
+ utils.logBullet(targetUri);
95
+ await utils.openInBrowser(targetUri);
96
+ await (0, prompt_1.promptOnce)({
97
+ type: "input",
98
+ message: "Press Enter once you have installed or configured the Firebase GitHub app to access your GitHub repo.",
99
+ });
100
+ conn = await devConnect.getConnection(projectId, location, connectionId);
101
+ }
102
+ return conn;
103
+ }
104
+ async function getOrCreateOauthConnection(projectId, location) {
105
+ let conn;
106
+ try {
107
+ conn = await devConnect.getConnection(projectId, location, APPHOSTING_OAUTH_CONN_NAME);
108
+ }
109
+ catch (err) {
110
+ if (err.status === 404) {
111
+ await ensureSecretManagerAdminGrant(projectId);
112
+ conn = await createConnection(projectId, location, APPHOSTING_OAUTH_CONN_NAME);
113
+ }
114
+ else {
115
+ throw err;
116
+ }
117
+ }
118
+ while (conn.installationState.stage === "PENDING_USER_OAUTH") {
119
+ utils.logBullet("You must authorize the Firebase GitHub app.");
120
+ utils.logBullet("Sign in to GitHub and authorize Firebase GitHub app:");
121
+ const { url, cleanup } = await utils.openInBrowserPopup(conn.installationState.actionUri, "Authorize the GitHub app");
122
+ utils.logBullet(`\t${url}`);
123
+ await (0, prompt_1.promptOnce)({
124
+ type: "input",
125
+ message: "Press Enter once you have authorized the app",
126
+ });
127
+ cleanup();
128
+ const { projectId, location, id } = parseConnectionName(conn.name);
129
+ conn = await devConnect.getConnection(projectId, location, id);
130
+ }
131
+ return conn;
132
+ }
133
+ exports.getOrCreateOauthConnection = getOrCreateOauthConnection;
134
+ async function promptCloneUri(projectId, connections) {
135
+ const { cloneUris, cloneUriToConnection } = await fetchAllRepositories(projectId, connections);
136
+ const cloneUri = await (0, prompt_1.promptOnce)({
137
+ type: "autocomplete",
138
+ name: "cloneUri",
139
+ message: "Which of the following repositories would you like to deploy?",
140
+ source: (_, input = "") => {
141
+ return new Promise((resolve) => resolve([
142
+ new inquirer.Separator(),
143
+ {
144
+ name: "Missing a repo? Select this option to configure your GitHub connection settings",
145
+ value: ADD_CONN_CHOICE,
146
+ },
147
+ new inquirer.Separator(),
148
+ ...fuzzy
149
+ .filter(input, cloneUris, {
150
+ extract: (uri) => extractRepoSlugFromUri(uri) || "",
151
+ })
152
+ .map((result) => {
153
+ return {
154
+ name: extractRepoSlugFromUri(result.original) || "",
155
+ value: result.original,
156
+ };
157
+ }),
158
+ ]));
159
+ },
160
+ });
161
+ return { cloneUri, connection: cloneUriToConnection[cloneUri] };
162
+ }
163
+ async function ensureSecretManagerAdminGrant(projectId) {
164
+ const projectNumber = await (0, getProjectNumber_1.getProjectNumber)({ projectId });
165
+ const dcsaEmail = devConnect.serviceAgentEmail(projectNumber);
166
+ const alreadyGranted = await rm.serviceAccountHasRoles(projectId, dcsaEmail, ["roles/secretmanager.admin"], true);
167
+ if (alreadyGranted) {
168
+ utils.logBullet("secret manager admin role already granted");
169
+ return;
170
+ }
171
+ utils.logBullet("To create a new GitHub connection, Secret Manager Admin role (roles/secretmanager.admin) is required on the Developer Connect Service Agent.");
172
+ const grant = await (0, prompt_1.promptOnce)({
173
+ type: "confirm",
174
+ message: "Grant the required role to the Developer Connect Service Agent?",
175
+ });
176
+ if (!grant) {
177
+ utils.logBullet("You, or your project administrator, should run the following command to grant the required role:\n\n" +
178
+ "You, or your project adminstrator, can run the following command to grant the required role manually:\n\n" +
179
+ `\tgcloud projects add-iam-policy-binding ${projectId} \\\n` +
180
+ `\t --member="serviceAccount:${dcsaEmail} \\\n` +
181
+ `\t --role="roles/secretmanager.admin\n`);
182
+ throw new error_1.FirebaseError("Insufficient IAM permissions to create a new connection to GitHub");
183
+ }
184
+ try {
185
+ await rm.addServiceAccountToRoles(projectId, dcsaEmail, ["roles/secretmanager.admin"], true);
186
+ }
187
+ catch (e) {
188
+ if ((e === null || e === void 0 ? void 0 : e.code) === 400 || (e === null || e === void 0 ? void 0 : e.status) === 400) {
189
+ await devConnect.generateP4SA(projectNumber);
190
+ await rm.addServiceAccountToRoles(projectId, dcsaEmail, ["roles/secretmanager.admin"], true);
191
+ }
192
+ else {
193
+ throw e;
194
+ }
195
+ }
196
+ utils.logSuccess("Successfully granted the required role to the Developer Connect Service Agent!");
197
+ }
198
+ exports.ensureSecretManagerAdminGrant = ensureSecretManagerAdminGrant;
199
+ async function createConnection(projectId, location, connectionId, githubConfig) {
200
+ const op = await devConnect.createConnection(projectId, location, connectionId, githubConfig);
201
+ const conn = await poller.pollOperation(Object.assign(Object.assign({}, devConnectPollerOptions), { pollerName: `create-${location}-${connectionId}`, operationResourceName: op.name }));
202
+ return conn;
203
+ }
204
+ exports.createConnection = createConnection;
205
+ async function getOrCreateConnection(projectId, location, connectionId, githubConfig) {
206
+ let conn;
207
+ try {
208
+ conn = await devConnect.getConnection(projectId, location, connectionId);
209
+ }
210
+ catch (err) {
211
+ if (err.status === 404) {
212
+ utils.logBullet("creating connection");
213
+ conn = await createConnection(projectId, location, connectionId, githubConfig);
214
+ }
215
+ else {
216
+ throw err;
217
+ }
218
+ }
219
+ return conn;
220
+ }
221
+ exports.getOrCreateConnection = getOrCreateConnection;
222
+ async function getOrCreateRepository(projectId, location, connectionId, cloneUri) {
223
+ const repositoryId = generateRepositoryId(cloneUri);
224
+ if (!repositoryId) {
225
+ throw new error_1.FirebaseError(`Failed to generate repositoryId for URI "${cloneUri}".`);
226
+ }
227
+ let repo;
228
+ try {
229
+ repo = await devConnect.getGitRepositoryLink(projectId, location, connectionId, repositoryId);
230
+ }
231
+ catch (err) {
232
+ if (err.status === 404) {
233
+ const op = await devConnect.createGitRepositoryLink(projectId, location, connectionId, repositoryId, cloneUri);
234
+ repo = await poller.pollOperation(Object.assign(Object.assign({}, devConnectPollerOptions), { pollerName: `create-${location}-${connectionId}-${repositoryId}`, operationResourceName: op.name }));
235
+ }
236
+ else {
237
+ throw err;
238
+ }
239
+ }
240
+ return repo;
241
+ }
242
+ exports.getOrCreateRepository = getOrCreateRepository;
243
+ async function listAppHostingConnections(projectId) {
244
+ const conns = await devConnect.listAllConnections(projectId, "-");
245
+ return conns.filter((conn) => APPHOSTING_CONN_PATTERN.test(conn.name) &&
246
+ conn.installationState.stage === "COMPLETE" &&
247
+ !conn.disabled);
248
+ }
249
+ exports.listAppHostingConnections = listAppHostingConnections;
250
+ async function fetchAllRepositories(projectId, connections) {
251
+ const cloneUriToConnection = {};
252
+ for (const conn of connections) {
253
+ const { location, id } = parseConnectionName(conn.name);
254
+ const connectionRepos = await devConnect.listAllLinkableGitRepositories(projectId, location, id);
255
+ connectionRepos.forEach((repo) => {
256
+ cloneUriToConnection[repo.cloneUri] = conn;
257
+ });
258
+ }
259
+ return { cloneUris: Object.keys(cloneUriToConnection), cloneUriToConnection };
260
+ }
261
+ exports.fetchAllRepositories = fetchAllRepositories;