firebase-tools 15.14.0 → 15.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api.js +2 -6
- package/lib/command.js +23 -29
- package/lib/commands/dataconnect-compile.js +6 -6
- package/lib/commands/dataconnect-execute.js +1 -1
- package/lib/commands/dataconnect-sdk-generate.js +3 -3
- package/lib/commands/dataconnect-services-list.js +1 -1
- package/lib/commands/dataconnect-sql-diff.js +3 -3
- package/lib/commands/dataconnect-sql-grant.js +2 -2
- package/lib/commands/dataconnect-sql-migrate.js +4 -4
- package/lib/commands/dataconnect-sql-setup.js +2 -2
- package/lib/commands/dataconnect-sql-shell.js +4 -4
- package/lib/commands/ext-dev-usage.js +0 -2
- package/lib/commands/init.js +3 -3
- package/lib/commands/open.js +1 -1
- package/lib/commands/setup-emulators-dataconnect.js +1 -1
- package/lib/dataconnect/freeTrial.js +2 -2
- package/lib/dataconnect/load.js +2 -2
- package/lib/dataconnect/provisionCloudSql.js +3 -3
- package/lib/dataconnect/schemaMigration.js +11 -11
- package/lib/dataconnect/webhook.js +1 -1
- package/lib/deploy/functions/backend.js +1 -1
- package/lib/deploy/functions/build.js +3 -3
- package/lib/deploy/functions/deploy.js +5 -2
- package/lib/deploy/functions/prepare.js +53 -0
- package/lib/deploy/functions/release/fabricator.js +59 -46
- package/lib/deploy/functions/release/planner.js +1 -1
- package/lib/deploy/functions/runtimes/dart/index.js +3 -1
- package/lib/deploy/functions/runtimes/dart/triggerSupport.js +123 -0
- package/lib/deploy/functions/runtimes/index.js +1 -4
- package/lib/deploy/functions/services/ailogic.js +12 -1
- package/lib/deploy/functions/services/dataconnect.js +1 -1
- package/lib/emulator/constants.js +1 -1
- package/lib/emulator/controller.js +2 -2
- package/lib/emulator/dataconnectEmulator.js +14 -14
- package/lib/emulator/dataconnectToolkitController.js +2 -2
- package/lib/emulator/downloadableEmulatorInfo.json +31 -31
- package/lib/emulator/extensionsEmulator.js +1 -2
- package/lib/emulator/functionsEmulator.js +15 -0
- package/lib/emulator/hub.js +3 -3
- package/lib/emulator/hubExport.js +2 -2
- package/lib/emulator/initEmulators.js +1 -1
- package/lib/experiments.js +10 -5
- package/lib/gcp/ailogic.js +6 -3
- package/lib/gcp/runv2.js +9 -2
- package/lib/init/features/dataconnect/index.js +7 -7
- package/lib/init/features/dataconnect/resolver.js +2 -2
- package/lib/init/features/dataconnect/sdk.js +8 -8
- package/lib/init/features/functions/index.js +1 -1
- package/lib/mcp/index.js +0 -1
- package/lib/mcp/prompts/dataconnect/schema.js +6 -6
- package/lib/mcp/resources/guides/init_data_connect.js +2 -2
- package/lib/mcp/resources/guides/init_firestore.js +1 -1
- package/lib/mcp/tools/core/init.js +9 -9
- package/lib/mcp/tools/dataconnect/compile.js +5 -5
- package/lib/mcp/tools/dataconnect/execute.js +6 -6
- package/lib/mcp/tools/dataconnect/list_services.js +7 -7
- package/lib/mcp/util/dataconnect/content.js +19 -19
- package/lib/tsconfig.compile.tsbuildinfo +1 -1
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +16 -4
- package/templates/init/functions/dart/pubspec.yaml +6 -7
- package/templates/init/functions/dart/server.dart +3 -1
- package/lib/shortenUrl.js +0 -28
package/lib/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.crashlyticsApiOrigin = exports.messagingApiOrigin = 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.
|
|
4
|
-
exports.developerKnowledgeOrigin = exports.cloudTestingOrigin = exports.appTestingOrigin = exports.cloudAiCompanionOrigin = exports.aiLogicProxyOrigin = exports.vertexAIOrigin = exports.cloudSQLAdminOrigin = exports.dataConnectLocalConnString = exports.dataconnectP4SADomain = exports.dataconnectOrigin = exports.githubClientSecret = exports.githubClientId = exports.computeOrigin = exports.secretManagerOrigin = exports.githubApiOrigin = exports.githubOrigin = exports.studioApiOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin =
|
|
3
|
+
exports.hostingApiOrigin = exports.firebaseStorageOrigin = exports.storageOrigin = exports.runtimeconfigOrigin = exports.rulesOrigin = exports.resourceManagerOrigin = exports.crashlyticsApiOrigin = exports.messagingApiOrigin = 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.consoleOrigin = exports.authManagementOrigin = exports.authOrigin = exports.apphostingGitHubAppInstallationURL = exports.apphostingP4SADomain = exports.apphostingOrigin = exports.appDistributionOrigin = exports.artifactRegistryDomain = exports.developerConnectP4SADomain = exports.developerConnectOrigin = exports.containerRegistryDomain = exports.cloudMonitoringOrigin = exports.cloudloggingOrigin = exports.cloudbillingOrigin = exports.clientSecret = exports.clientId = exports.authProxyOrigin = void 0;
|
|
4
|
+
exports.developerKnowledgeOrigin = exports.cloudTestingOrigin = exports.appTestingOrigin = exports.cloudAiCompanionOrigin = exports.aiLogicProxyOrigin = exports.vertexAIOrigin = exports.cloudSQLAdminOrigin = exports.dataConnectLocalConnString = exports.dataconnectP4SADomain = exports.dataconnectOrigin = exports.githubClientSecret = exports.githubClientId = exports.computeOrigin = exports.secretManagerOrigin = exports.githubApiOrigin = exports.githubOrigin = exports.studioApiOrigin = exports.serviceUsageOrigin = exports.cloudRunApiOrigin = void 0;
|
|
5
5
|
exports.getScopes = getScopes;
|
|
6
6
|
exports.setScopes = setScopes;
|
|
7
7
|
const constants_1 = require("./emulator/constants");
|
|
@@ -43,10 +43,6 @@ const authManagementOrigin = () => utils.envOverride("FIREBASE_AUTH_MANAGEMENT_U
|
|
|
43
43
|
exports.authManagementOrigin = authManagementOrigin;
|
|
44
44
|
const consoleOrigin = () => utils.envOverride("FIREBASE_CONSOLE_URL", "https://console.firebase.google.com");
|
|
45
45
|
exports.consoleOrigin = consoleOrigin;
|
|
46
|
-
const dynamicLinksOrigin = () => utils.envOverride("FIREBASE_DYNAMIC_LINKS_URL", "https://firebasedynamiclinks.googleapis.com");
|
|
47
|
-
exports.dynamicLinksOrigin = dynamicLinksOrigin;
|
|
48
|
-
const dynamicLinksKey = () => utils.envOverride("FIREBASE_DYNAMIC_LINKS_KEY", "AIzaSyB6PtY5vuiSB8MNgt20mQffkOlunZnHYiQ");
|
|
49
|
-
exports.dynamicLinksKey = dynamicLinksKey;
|
|
50
46
|
const eventarcOrigin = () => utils.envOverride("EVENTARC_URL", "https://eventarc.googleapis.com");
|
|
51
47
|
exports.eventarcOrigin = eventarcOrigin;
|
|
52
48
|
const firebaseApiOrigin = () => utils.envOverride("FIREBASE_API_URL", "https://firebase.googleapis.com");
|
package/lib/command.js
CHANGED
|
@@ -111,23 +111,22 @@ class Command {
|
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
const duration = Math.floor((process.uptime() - start) * 1000);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
const trackSuccess = (0, track_1.trackGA4)("command_execution", {
|
|
115
|
+
command_name: this.name,
|
|
116
|
+
result: "success",
|
|
117
|
+
interactive: (0, utils_1.getInheritedOption)(options, "nonInteractive") ? "false" : "true",
|
|
118
|
+
}, duration);
|
|
119
|
+
if (!isEmulator) {
|
|
120
|
+
await (0, utils_1.withTimeout)(5000, trackSuccess);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
await (0, utils_1.withTimeout)(5000, Promise.all([
|
|
124
|
+
trackSuccess,
|
|
125
|
+
(0, track_1.trackEmulator)("command_success", {
|
|
123
126
|
command_name: this.name,
|
|
124
127
|
duration,
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
await (0, utils_1.withTimeout)(1000, Promise.all(tracks));
|
|
128
|
-
}
|
|
129
|
-
catch (gaErr) {
|
|
130
|
-
logger_1.logger.debug("Analytics tracking failed during success path:", gaErr);
|
|
128
|
+
}),
|
|
129
|
+
]));
|
|
131
130
|
}
|
|
132
131
|
process.exit();
|
|
133
132
|
})
|
|
@@ -141,25 +140,20 @@ class Command {
|
|
|
141
140
|
});
|
|
142
141
|
}
|
|
143
142
|
const duration = Math.floor((process.uptime() - start) * 1000);
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
await (0, utils_1.withTimeout)(5000, Promise.all([
|
|
144
|
+
(0, track_1.trackGA4)("command_execution", {
|
|
146
145
|
command_name: this.name,
|
|
147
146
|
result: "error",
|
|
148
147
|
interactive: (0, utils_1.getInheritedOption)(options, "nonInteractive") ? "false" : "true",
|
|
149
|
-
}, duration)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
tracks.push((0, track_1.trackEmulator)("command_error", {
|
|
148
|
+
}, duration),
|
|
149
|
+
isEmulator
|
|
150
|
+
? (0, track_1.trackEmulator)("command_error", {
|
|
153
151
|
command_name: this.name,
|
|
154
152
|
duration,
|
|
155
|
-
error_type: err
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
catch (gaErr) {
|
|
161
|
-
logger_1.logger.debug("Analytics tracking failed during error path:", gaErr);
|
|
162
|
-
}
|
|
153
|
+
error_type: err.exit === 1 ? "user" : "unexpected",
|
|
154
|
+
})
|
|
155
|
+
: Promise.resolve(),
|
|
156
|
+
]));
|
|
163
157
|
client.errorOut(err);
|
|
164
158
|
});
|
|
165
159
|
});
|
|
@@ -12,18 +12,18 @@ const hub_1 = require("../emulator/hub");
|
|
|
12
12
|
const build_1 = require("../dataconnect/build");
|
|
13
13
|
const error_1 = require("../error");
|
|
14
14
|
exports.command = new command_1.Command("dataconnect:compile")
|
|
15
|
-
.description("compile your
|
|
16
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
17
|
-
.option("--location <location>", "the location of the
|
|
15
|
+
.description("compile your SQL Connect schema and connector config and GQL files.")
|
|
16
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service. If not provided, compiles all services.")
|
|
17
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
18
18
|
.action(async (options) => {
|
|
19
19
|
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
20
20
|
const config = options.config;
|
|
21
21
|
if (!config || !config.has("dataconnect")) {
|
|
22
|
-
throw new error_1.FirebaseError(`No
|
|
22
|
+
throw new error_1.FirebaseError(`No SQL Connect project directory found. Please run ${clc.bold("firebase init dataconnect")} to set it up first.`);
|
|
23
23
|
}
|
|
24
24
|
const serviceInfos = await (0, load_1.pickServices)(projectId || hub_1.EmulatorHub.MISSING_PROJECT_PLACEHOLDER, config, options.service, options.location);
|
|
25
25
|
if (!serviceInfos.length) {
|
|
26
|
-
throw new error_1.FirebaseError("No
|
|
26
|
+
throw new error_1.FirebaseError("No SQL Connect services found to compile.");
|
|
27
27
|
}
|
|
28
28
|
for (const serviceInfo of serviceInfos) {
|
|
29
29
|
const configDir = serviceInfo.sourceDirectory;
|
|
@@ -41,6 +41,6 @@ exports.command = new command_1.Command("dataconnect:compile")
|
|
|
41
41
|
configDir,
|
|
42
42
|
account,
|
|
43
43
|
});
|
|
44
|
-
(0, utils_1.logLabeledSuccess)("dataconnect", `Successfully compiled
|
|
44
|
+
(0, utils_1.logLabeledSuccess)("dataconnect", `Successfully compiled SQL Connect service: ${clc.bold(serviceInfo.dataConnectYaml.serviceId)}`);
|
|
45
45
|
}
|
|
46
46
|
});
|
|
@@ -23,7 +23,7 @@ const logger_1 = require("../logger");
|
|
|
23
23
|
const responseToError_1 = require("../responseToError");
|
|
24
24
|
let stdinUsedFor = undefined;
|
|
25
25
|
exports.command = new command_1.Command("dataconnect:execute [file] [operationName]")
|
|
26
|
-
.description("execute a
|
|
26
|
+
.description("execute a SQL Connect query or mutation. If FIREBASE_DATACONNECT_EMULATOR_HOST is set (such as during 'firebase emulator:exec', executes against the emulator instead.")
|
|
27
27
|
.option("--service <serviceId>", "The service ID to execute against (optional if there's only one service)")
|
|
28
28
|
.option("--location <locationId>", "The location ID to execute against (optional if there's only one service). Ignored by the emulator.")
|
|
29
29
|
.option("--vars, --variables <vars>", "Supply variables to the operation execution, which must be a JSON object whose keys are variable names. If vars begin with the character @, the rest is interpreted as a file name to read from, or - to read from stdin.")
|
|
@@ -15,9 +15,9 @@ const error_1 = require("../error");
|
|
|
15
15
|
const init_1 = require("./init");
|
|
16
16
|
const hub_1 = require("../emulator/hub");
|
|
17
17
|
exports.command = new command_1.Command("dataconnect:sdk:generate")
|
|
18
|
-
.description("generate typed SDKs to use
|
|
19
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
20
|
-
.option("--location <location>", "the location of the
|
|
18
|
+
.description("generate typed SDKs to use SQL Connect in your apps")
|
|
19
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service. If not provided, generates SDKs for all services.")
|
|
20
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
21
21
|
.option("--watch", "watch for changes to your connector GQL files and regenerate your SDKs when updates occur")
|
|
22
22
|
.action(async (options) => {
|
|
23
23
|
const projectId = (0, projectUtils_1.getProjectId)(options);
|
|
@@ -10,7 +10,7 @@ const requirePermissions_1 = require("../requirePermissions");
|
|
|
10
10
|
const ensureApis_1 = require("../dataconnect/ensureApis");
|
|
11
11
|
const Table = require("cli-table3");
|
|
12
12
|
exports.command = new command_1.Command("dataconnect:services:list")
|
|
13
|
-
.description("list all deployed
|
|
13
|
+
.description("list all deployed SQL Connect services")
|
|
14
14
|
.before(requirePermissions_1.requirePermissions, [
|
|
15
15
|
"dataconnect.services.list",
|
|
16
16
|
"dataconnect.schemas.list",
|
|
@@ -10,9 +10,9 @@ const schemaMigration_1 = require("../dataconnect/schemaMigration");
|
|
|
10
10
|
const requireAuth_1 = require("../requireAuth");
|
|
11
11
|
const types_1 = require("../dataconnect/types");
|
|
12
12
|
exports.command = new command_1.Command("dataconnect:sql:diff")
|
|
13
|
-
.description("display the differences between the local
|
|
14
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
15
|
-
.option("--location <location>", "the location of the
|
|
13
|
+
.description("display the differences between the local SQL Connect schema and your CloudSQL database's schema")
|
|
14
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service")
|
|
15
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
16
16
|
.before(requirePermissions_1.requirePermissions, [
|
|
17
17
|
"firebasedataconnect.services.list",
|
|
18
18
|
"firebasedataconnect.schemas.list",
|
|
@@ -17,8 +17,8 @@ exports.command = new command_1.Command("dataconnect:sql:grant")
|
|
|
17
17
|
.description("grants the SQL role <role> to the provided user or service account <email>")
|
|
18
18
|
.option("-R, --role <role>", "The SQL role to grant. One of: owner, writer, or reader.")
|
|
19
19
|
.option("-E, --email <email>", "The email of the user or service account we would like to grant the role to.")
|
|
20
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
21
|
-
.option("--location <location>", "the location of the
|
|
20
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service")
|
|
21
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
22
22
|
.before(requirePermissions_1.requirePermissions, ["firebasedataconnect.services.list"])
|
|
23
23
|
.before(requireAuth_1.requireAuth)
|
|
24
24
|
.action(async (options) => {
|
|
@@ -12,9 +12,9 @@ const ensureApis_1 = require("../dataconnect/ensureApis");
|
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
const types_1 = require("../dataconnect/types");
|
|
14
14
|
exports.command = new command_1.Command("dataconnect:sql:migrate")
|
|
15
|
-
.description("migrate your CloudSQL database's schema to match your local
|
|
16
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
17
|
-
.option("--location <location>", "the location of the
|
|
15
|
+
.description("migrate your CloudSQL database's schema to match your local SQL Connect schema")
|
|
16
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service")
|
|
17
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
18
18
|
.before(requirePermissions_1.requirePermissions, [
|
|
19
19
|
"firebasedataconnect.services.list",
|
|
20
20
|
"firebasedataconnect.schemas.list",
|
|
@@ -40,7 +40,7 @@ exports.command = new command_1.Command("dataconnect:sql:migrate")
|
|
|
40
40
|
?.schemaValidation,
|
|
41
41
|
});
|
|
42
42
|
if (diffs.length) {
|
|
43
|
-
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema sucessfully migrated! Run 'firebase deploy' to deploy your new schema to your
|
|
43
|
+
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema sucessfully migrated! Run 'firebase deploy' to deploy your new schema to your SQL Connect service.`);
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
46
46
|
(0, utils_1.logLabeledSuccess)("dataconnect", "Database schema is already up to date!");
|
|
@@ -14,8 +14,8 @@ const load_1 = require("../dataconnect/load");
|
|
|
14
14
|
const types_1 = require("../dataconnect/types");
|
|
15
15
|
exports.command = new command_1.Command("dataconnect:sql:setup")
|
|
16
16
|
.description("set up your CloudSQL database")
|
|
17
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
18
|
-
.option("--location <location>", "the location of the
|
|
17
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service")
|
|
18
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
19
19
|
.before(requirePermissions_1.requirePermissions, [
|
|
20
20
|
"firebasedataconnect.services.list",
|
|
21
21
|
"firebasedataconnect.schemas.list",
|
|
@@ -74,9 +74,9 @@ async function mainShellLoop(conn) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
exports.command = new command_1.Command("dataconnect:sql:shell")
|
|
77
|
-
.description("start a shell connected directly to your
|
|
78
|
-
.option("--service <serviceId>", "the serviceId of the
|
|
79
|
-
.option("--location <location>", "the location of the
|
|
77
|
+
.description("start a shell connected directly to your SQL Connect service's linked CloudSQL instance")
|
|
78
|
+
.option("--service <serviceId>", "the serviceId of the SQL Connect service")
|
|
79
|
+
.option("--location <location>", "the location of the SQL Connect service. Only needed if service ID is used in multiple locations.")
|
|
80
80
|
.before(requirePermissions_1.requirePermissions, ["firebasedataconnect.services.list", "cloudsql.instances.connect"])
|
|
81
81
|
.before(requireAuth_1.requireAuth)
|
|
82
82
|
.action(async (options) => {
|
|
@@ -106,7 +106,7 @@ exports.command = new command_1.Command("dataconnect:sql:shell")
|
|
|
106
106
|
const conn = await pool.connect();
|
|
107
107
|
await conn.query(`SET search_path TO "${schemaName}"`);
|
|
108
108
|
logger_1.logger.info(`Logged in as ${username}`);
|
|
109
|
-
logger_1.logger.info(clc.cyan("Welcome to
|
|
109
|
+
logger_1.logger.info(clc.cyan("Welcome to SQL Connect Cloud SQL Shell"));
|
|
110
110
|
logger_1.logger.info(clc.gray("Type your your SQL query or '.exit' to quit, queries should end with ';' or add empty line to execute."));
|
|
111
111
|
await mainShellLoop(conn);
|
|
112
112
|
logger_1.logger.info(clc.yellow("Exiting shell..."));
|
|
@@ -14,7 +14,6 @@ const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
|
14
14
|
const error_1 = require("../error");
|
|
15
15
|
const logger_1 = require("../logger");
|
|
16
16
|
const prompt_1 = require("../prompt");
|
|
17
|
-
const shortenUrl_1 = require("../shortenUrl");
|
|
18
17
|
exports.command = new command_1.Command("ext:dev:usage <publisherId>")
|
|
19
18
|
.description("get usage statistics for an extension")
|
|
20
19
|
.help("use this command to get the usage of extensions you published. " +
|
|
@@ -134,6 +133,5 @@ async function buildCloudMonitoringLink(args) {
|
|
|
134
133
|
let uri = `https://console.cloud.google.com/monitoring/metrics-explorer?project=${args.projectNumber}` +
|
|
135
134
|
`&pageState=${JSON.stringify(pageState)}`;
|
|
136
135
|
uri = encodeURI(uri);
|
|
137
|
-
uri = await (0, shortenUrl_1.shortenUrl)(uri);
|
|
138
136
|
return uri;
|
|
139
137
|
}
|
package/lib/commands/init.js
CHANGED
|
@@ -27,7 +27,7 @@ function isOutside(from, to) {
|
|
|
27
27
|
let choices = [
|
|
28
28
|
{
|
|
29
29
|
value: "dataconnect",
|
|
30
|
-
name: "
|
|
30
|
+
name: "SQL Connect: Set up a Firebase SQL Connect service",
|
|
31
31
|
checked: false,
|
|
32
32
|
},
|
|
33
33
|
{
|
|
@@ -84,7 +84,7 @@ let choices = [
|
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
value: "dataconnect:sdk",
|
|
87
|
-
name: "
|
|
87
|
+
name: "SQL Connect: Set up a generated SDK for your Firebase SQL Connect service",
|
|
88
88
|
checked: false,
|
|
89
89
|
hidden: true,
|
|
90
90
|
},
|
|
@@ -97,7 +97,7 @@ let choices = [
|
|
|
97
97
|
if ((0, experiments_1.isEnabled)("fdcwebhooks")) {
|
|
98
98
|
choices.push({
|
|
99
99
|
value: "dataconnect:resolver",
|
|
100
|
-
name: "
|
|
100
|
+
name: "SQL Connect: Set up a custom resolver for your Firebase SQL Connect service",
|
|
101
101
|
checked: false,
|
|
102
102
|
hidden: true,
|
|
103
103
|
});
|
package/lib/commands/open.js
CHANGED
|
@@ -20,7 +20,7 @@ const LINKS = [
|
|
|
20
20
|
{ name: "Crash Reporting", arg: "crash", consolePath: "/crashlytics" },
|
|
21
21
|
{ name: "Database: Data", arg: "database", consolePath: "/database/data" },
|
|
22
22
|
{ name: "Database: Rules", arg: "database:rules", consolePath: "/database/rules" },
|
|
23
|
-
{ name: "
|
|
23
|
+
{ name: "SQL Connect", arg: "dataconnect", consolePath: "/dataconnect" },
|
|
24
24
|
{ name: "Docs", arg: "docs", url: "https://firebase.google.com/docs" },
|
|
25
25
|
{ name: "Dynamic Links", arg: "links", consolePath: "/durablelinks" },
|
|
26
26
|
{ name: "Extensions", arg: "extensions", consolePath: "/extensions" },
|
|
@@ -11,7 +11,7 @@ exports.command = new command_1.Command(`setup:emulators:${NAME}`)
|
|
|
11
11
|
.action(async (options) => {
|
|
12
12
|
await (0, downloadableEmulators_1.downloadIfNecessary)(NAME);
|
|
13
13
|
if (!options.config) {
|
|
14
|
-
logger_1.logger.info("Not currently in a Firebase project directory. Run this command from a project directory to configure the
|
|
14
|
+
logger_1.logger.info("Not currently in a Firebase project directory. Run this command from a project directory to configure the SQL Connect emulator.");
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
logger_1.logger.info("Setup complete!");
|
|
@@ -30,11 +30,11 @@ async function checkFreeTrialInstanceUsed(projectId) {
|
|
|
30
30
|
return used;
|
|
31
31
|
}
|
|
32
32
|
function upgradeInstructions(projectId, trialUsed) {
|
|
33
|
-
return `To provision a ${trialUsed ? "paid CloudSQL Postgres instance" : "CloudSQL Postgres instance on the Firebase
|
|
33
|
+
return `To provision a ${trialUsed ? "paid CloudSQL Postgres instance" : "CloudSQL Postgres instance on the Firebase SQL Connect no-cost trial"}:
|
|
34
34
|
|
|
35
35
|
1. Please upgrade to the pay-as-you-go (Blaze) billing plan. Visit the following page:
|
|
36
36
|
|
|
37
37
|
https://console.firebase.google.com/project/${projectId}/usage/details
|
|
38
38
|
|
|
39
|
-
2. Run ${clc.bold("firebase deploy --only dataconnect")} to deploy your
|
|
39
|
+
2. Run ${clc.bold("firebase deploy --only dataconnect")} to deploy your SQL Connect service.`;
|
|
40
40
|
}
|
package/lib/dataconnect/load.js
CHANGED
|
@@ -29,8 +29,8 @@ async function pickOneService(projectId, config, service, location) {
|
|
|
29
29
|
async function pickServices(projectId, config, serviceId, location) {
|
|
30
30
|
const serviceInfos = await loadAll(projectId, config);
|
|
31
31
|
if (serviceInfos.length === 0) {
|
|
32
|
-
throw new error_1.FirebaseError("No
|
|
33
|
-
`\nYou can run ${clc.bold("firebase init dataconnect")} to add a
|
|
32
|
+
throw new error_1.FirebaseError("No SQL Connect services found in firebase.json. " +
|
|
33
|
+
`\nYou can run ${clc.bold("firebase init dataconnect")} to add a SQL Connect service.`);
|
|
34
34
|
}
|
|
35
35
|
const matchingServices = serviceInfos.filter((i) => (!serviceId || i.dataConnectYaml.serviceId === serviceId) &&
|
|
36
36
|
(!location || i.dataConnectYaml.location === location));
|
|
@@ -49,12 +49,12 @@ async function upsertInstance(stats, args) {
|
|
|
49
49
|
const why = getUpdateReason(existingInstance, requireGoogleMlIntegration);
|
|
50
50
|
if (why) {
|
|
51
51
|
if (dryRun) {
|
|
52
|
-
utils.logLabeledBullet("dataconnect", `Cloud SQL instance ${clc.bold(instanceId)} settings are not compatible with Firebase
|
|
52
|
+
utils.logLabeledBullet("dataconnect", `Cloud SQL instance ${clc.bold(instanceId)} settings are not compatible with Firebase SQL Connect. ` +
|
|
53
53
|
`It will be updated on your next deploy.` +
|
|
54
54
|
why);
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
-
utils.logLabeledBullet("dataconnect", `Cloud SQL instance ${clc.bold(instanceId)} settings are not compatible with Firebase
|
|
57
|
+
utils.logLabeledBullet("dataconnect", `Cloud SQL instance ${clc.bold(instanceId)} settings are not compatible with Firebase SQL Connect. ` +
|
|
58
58
|
why);
|
|
59
59
|
stats.action = "update";
|
|
60
60
|
await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.updateInstanceForDataConnect(existingInstance, requireGoogleMlIntegration), "Updating your Cloud SQL instance...");
|
|
@@ -92,7 +92,7 @@ async function createInstance(args) {
|
|
|
92
92
|
function cloudSQLBeingCreated(projectId, instanceId, isFreeTrial, billingEnabled) {
|
|
93
93
|
return (`Cloud SQL Instance ${clc.bold(instanceId)} is being created.` +
|
|
94
94
|
(isFreeTrial
|
|
95
|
-
? `\nThis instance is provided under the terms of the
|
|
95
|
+
? `\nThis instance is provided under the terms of the SQL Connect no-cost trial ${(0, freeTrial_1.freeTrialTermsLink)()}`
|
|
96
96
|
: "") +
|
|
97
97
|
`\n
|
|
98
98
|
Meanwhile, your data are saved in a temporary database and will be migrated once complete.` +
|
|
@@ -248,7 +248,7 @@ async function grantRoleToUserInSchema(options, schema) {
|
|
|
248
248
|
await ensureServiceIsConnectedToCloudSql(serviceName, instanceName, databaseId, false, schemaName);
|
|
249
249
|
const schemaSetupStatus = await setupSchemaIfNecessary(instanceId, databaseId, schemaName, options);
|
|
250
250
|
if (schemaSetupStatus !== permissionsSetup_1.SchemaSetupStatus.GreenField && role === "owner") {
|
|
251
|
-
throw new error_1.FirebaseError(`Owner rule isn't available in ${schemaSetupStatus} databases. If you would like
|
|
251
|
+
throw new error_1.FirebaseError(`Owner rule isn't available in ${schemaSetupStatus} databases. If you would like SQL Connect to manage and own your database schema, run 'firebase dataconnect:sql:setup'`);
|
|
252
252
|
}
|
|
253
253
|
await (0, permissionsSetup_1.grantRoleTo)(options, instanceId, databaseId, role, email, schemaName);
|
|
254
254
|
}
|
|
@@ -275,11 +275,11 @@ function getIdentifiers(schema) {
|
|
|
275
275
|
const postgresDatasource = schema.datasources.find((d) => d.postgresql);
|
|
276
276
|
const databaseId = postgresDatasource?.postgresql?.database;
|
|
277
277
|
if (!databaseId) {
|
|
278
|
-
throw new error_1.FirebaseError("
|
|
278
|
+
throw new error_1.FirebaseError("SQL Connect schema must have a postgres datasource with a database name.");
|
|
279
279
|
}
|
|
280
280
|
const instanceName = postgresDatasource?.postgresql?.cloudSql?.instance;
|
|
281
281
|
if (!instanceName) {
|
|
282
|
-
throw new error_1.FirebaseError("
|
|
282
|
+
throw new error_1.FirebaseError("SQL Connect schema must have a postgres datasource with a CloudSQL instance.");
|
|
283
283
|
}
|
|
284
284
|
const instanceId = instanceName.split("/").pop();
|
|
285
285
|
const schemaName = postgresDatasource?.postgresql?.schema || permissions_1.DEFAULT_SCHEMA;
|
|
@@ -325,9 +325,9 @@ async function handleIncompatibleSchemaError(args) {
|
|
|
325
325
|
}
|
|
326
326
|
const schemaInfo = await (0, permissionsSetup_1.getSchemaMetadata)(instanceId, databaseId, schemaName, options);
|
|
327
327
|
if (schemaInfo.setupStatus !== permissionsSetup_1.SchemaSetupStatus.GreenField) {
|
|
328
|
-
throw new error_1.FirebaseError(`Brownfield database are protected from SQL changes by
|
|
328
|
+
throw new error_1.FirebaseError(`Brownfield database are protected from SQL changes by SQL Connect.\n` +
|
|
329
329
|
`You can use the SQL diff generated by 'firebase dataconnect:sql:diff' to assist you in applying the required changes to your CloudSQL database. Connector deployment will succeed when there is no required diff changes.\n` +
|
|
330
|
-
`If you would like
|
|
330
|
+
`If you would like SQL Connect to manage your database schema, run 'firebase dataconnect:sql:setup'`);
|
|
331
331
|
}
|
|
332
332
|
if (!(await (0, permissionsSetup_1.checkSQLRoleIsGranted)(options, instanceId, databaseId, (0, permissions_1.firebaseowner)(databaseId, schemaName), (await (0, connect_1.getIAMUser)(options)).user))) {
|
|
333
333
|
if (!userIsCSQLAdmin) {
|
|
@@ -387,7 +387,7 @@ async function promptForSchemaMigration(options, instanceId, databaseId, err, va
|
|
|
387
387
|
return ans;
|
|
388
388
|
}
|
|
389
389
|
if (!validateOnly) {
|
|
390
|
-
throw new error_1.FirebaseError("Command aborted. Your database schema is incompatible with your
|
|
390
|
+
throw new error_1.FirebaseError("Command aborted. Your database schema is incompatible with your SQL Connect schema. Run `firebase dataconnect:sql:migrate` to migrate your database schema");
|
|
391
391
|
}
|
|
392
392
|
else if (options.force) {
|
|
393
393
|
return defaultChoice;
|
|
@@ -509,10 +509,10 @@ function displayStartSchemaDiff(validationMode) {
|
|
|
509
509
|
function displayNoSchemaDiff(instanceId, databaseId, validationMode) {
|
|
510
510
|
switch (validationMode) {
|
|
511
511
|
case "COMPATIBLE":
|
|
512
|
-
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema of ${instanceId}:${databaseId} is compatible with
|
|
512
|
+
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema of ${instanceId}:${databaseId} is compatible with SQL Connect Schema.`);
|
|
513
513
|
break;
|
|
514
514
|
case "STRICT":
|
|
515
|
-
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema of ${instanceId}:${databaseId} matches
|
|
515
|
+
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema of ${instanceId}:${databaseId} matches SQL Connect Schema exactly.`);
|
|
516
516
|
break;
|
|
517
517
|
}
|
|
518
518
|
}
|
|
@@ -522,21 +522,21 @@ function displaySchemaChanges(error, validationMode) {
|
|
|
522
522
|
{
|
|
523
523
|
switch (validationMode) {
|
|
524
524
|
case "COMPATIBLE":
|
|
525
|
-
(0, utils_1.logLabeledWarning)("dataconnect", `PostgreSQL schema is incompatible with the
|
|
525
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `PostgreSQL schema is incompatible with the SQL Connect Schema.
|
|
526
526
|
Those SQL statements will migrate it to be compatible:
|
|
527
527
|
|
|
528
528
|
${diffsToString(error.diffs)}
|
|
529
529
|
`);
|
|
530
530
|
break;
|
|
531
531
|
case "STRICT_AFTER_COMPATIBLE":
|
|
532
|
-
(0, utils_1.logLabeledBullet)("dataconnect", `PostgreSQL schema contains unused SQL objects not part of the
|
|
532
|
+
(0, utils_1.logLabeledBullet)("dataconnect", `PostgreSQL schema contains unused SQL objects not part of the SQL Connect Schema.
|
|
533
533
|
Those SQL statements will migrate it to match exactly:
|
|
534
534
|
|
|
535
535
|
${diffsToString(error.diffs)}
|
|
536
536
|
`);
|
|
537
537
|
break;
|
|
538
538
|
case "STRICT":
|
|
539
|
-
(0, utils_1.logLabeledWarning)("dataconnect", `PostgreSQL schema does not match the
|
|
539
|
+
(0, utils_1.logLabeledWarning)("dataconnect", `PostgreSQL schema does not match the SQL Connect Schema.
|
|
540
540
|
Those SQL statements will migrate it to match exactly:
|
|
541
541
|
|
|
542
542
|
${diffsToString(error.diffs)}
|
|
@@ -27,6 +27,6 @@ async function sendVSCodeMessage(body) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
catch (e) {
|
|
30
|
-
logger_1.logger.debug(`Could not find VSCode notification endpoint: ${e}. If you are not running the Firebase
|
|
30
|
+
logger_1.logger.debug(`Could not find VSCode notification endpoint: ${e}. If you are not running the Firebase SQL Connect VSCode extension, this is expected and not an issue.`);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -210,7 +210,7 @@ async function loadExistingBackend(ctx) {
|
|
|
210
210
|
existingBackend.endpoints[endpoint.region][endpoint.id] = endpoint;
|
|
211
211
|
}
|
|
212
212
|
unreachableRegions.gcfV1 = gcfV1Results.unreachable;
|
|
213
|
-
if (experiments.isEnabled("functionsrunapionly")) {
|
|
213
|
+
if (experiments.isEnabled("functionsrunapionly") || experiments.isEnabled("dartfunctions")) {
|
|
214
214
|
try {
|
|
215
215
|
const runServices = await run.listServices(ctx.projectId);
|
|
216
216
|
for (const service of runServices) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AllIngressSettings = exports.AllVpcEgressSettings = exports.AllFunctionsPlatforms = void 0;
|
|
3
|
+
exports.AllIngressSettings = exports.AllVpcEgressSettings = exports.AllFunctionsPlatforms = exports.REGION_TBD = void 0;
|
|
4
4
|
exports.empty = empty;
|
|
5
5
|
exports.of = of;
|
|
6
6
|
exports.isHttpsTriggered = isHttpsTriggered;
|
|
@@ -16,11 +16,11 @@ exports.toBackend = toBackend;
|
|
|
16
16
|
exports.applyPrefix = applyPrefix;
|
|
17
17
|
const backend = require("./backend");
|
|
18
18
|
const proto = require("../../gcp/proto");
|
|
19
|
-
const api = require("../../api");
|
|
20
19
|
const params = require("./params");
|
|
21
20
|
const error_1 = require("../../error");
|
|
22
21
|
const functional_1 = require("../../functional");
|
|
23
22
|
const cel_1 = require("./cel");
|
|
23
|
+
exports.REGION_TBD = "REGION_TBD";
|
|
24
24
|
function empty() {
|
|
25
25
|
return {
|
|
26
26
|
requiredAPIs: [],
|
|
@@ -175,7 +175,7 @@ function toBackend(build, paramValues) {
|
|
|
175
175
|
}
|
|
176
176
|
let regions = [];
|
|
177
177
|
if (!bdEndpoint.region) {
|
|
178
|
-
regions = [
|
|
178
|
+
regions = [exports.REGION_TBD];
|
|
179
179
|
}
|
|
180
180
|
else if (Array.isArray(bdEndpoint.region)) {
|
|
181
181
|
regions = params.resolveList(bdEndpoint.region, paramValues);
|
|
@@ -15,6 +15,7 @@ const gcf = require("../../gcp/cloudfunctions");
|
|
|
15
15
|
const gcfv2 = require("../../gcp/cloudfunctionsv2");
|
|
16
16
|
const backend = require("./backend");
|
|
17
17
|
const experiments = require("../../experiments");
|
|
18
|
+
const supported = require("./runtimes/supported");
|
|
18
19
|
const backend_1 = require("./backend");
|
|
19
20
|
const extensions_1 = require("../extensions");
|
|
20
21
|
const getProjectNumber_1 = require("../../getProjectNumber");
|
|
@@ -54,8 +55,10 @@ async function uploadSourceV2(projectId, projectNumber, source, wantBackend) {
|
|
|
54
55
|
file: source.functionsSourceV2,
|
|
55
56
|
stream: exports.createReadStream(source.functionsSourceV2),
|
|
56
57
|
};
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
const isDart = v2Endpoints.some((e) => supported.runtimeIsLanguage(e.runtime, "dart"));
|
|
59
|
+
const useApiOnly = experiments.isEnabled("functionsrunapionly") ||
|
|
60
|
+
(isDart && experiments.isEnabled("dartfunctions"));
|
|
61
|
+
if (!useApiOnly && !v2Endpoints.some((e) => e.platform === "run")) {
|
|
59
62
|
if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) {
|
|
60
63
|
(0, utils_1.logLabeledWarning)("functions", "GOOGLE_CLOUD_QUOTA_PROJECT is not usable when uploading source for Cloud Functions.");
|
|
61
64
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EVENTARC_SOURCE_ENV = void 0;
|
|
4
4
|
exports.prepare = prepare;
|
|
5
|
+
exports.matchRegionsForExisting = matchRegionsForExisting;
|
|
6
|
+
exports.resolveDefaultRegions = resolveDefaultRegions;
|
|
5
7
|
exports.inferDetailsFromExisting = inferDetailsFromExisting;
|
|
6
8
|
exports.updateEndpointTargetedStatus = updateEndpointTargetedStatus;
|
|
7
9
|
exports.inferBlockingDetails = inferBlockingDetails;
|
|
@@ -24,6 +26,7 @@ const ensure = require("./ensure");
|
|
|
24
26
|
const api_1 = require("../../api");
|
|
25
27
|
const functionsDeployHelper_1 = require("./functionsDeployHelper");
|
|
26
28
|
const utils_1 = require("../../utils");
|
|
29
|
+
const triggerSupport_1 = require("./runtimes/dart/triggerSupport");
|
|
27
30
|
const prepareFunctionsUpload_1 = require("./prepareFunctionsUpload");
|
|
28
31
|
const prompts_1 = require("./prompts");
|
|
29
32
|
const projectUtils_1 = require("../../projectUtils");
|
|
@@ -190,6 +193,7 @@ async function prepare(context, options, payload) {
|
|
|
190
193
|
payload.functions[codebase] = { wantBackend, haveBackend };
|
|
191
194
|
}
|
|
192
195
|
for (const [codebase, { wantBackend, haveBackend }] of Object.entries(payload.functions)) {
|
|
196
|
+
await resolveDefaultRegions(wantBackend, haveBackend);
|
|
193
197
|
inferDetailsFromExisting(wantBackend, haveBackend, codebaseUsesEnvs.includes(codebase));
|
|
194
198
|
await (0, triggerRegionHelper_1.ensureTriggerRegions)(wantBackend);
|
|
195
199
|
resolveCpuAndConcurrency(wantBackend);
|
|
@@ -200,6 +204,7 @@ async function prepare(context, options, payload) {
|
|
|
200
204
|
const haveBackend = backend.merge(...Object.values(haveBackends));
|
|
201
205
|
await ensureAllRequiredAPIsEnabled(projectNumber, wantBackend);
|
|
202
206
|
await warnIfNewGenkitFunctionIsMissingSecrets(wantBackend, haveBackend, options);
|
|
207
|
+
warnIfDartBackendHasUnsupportedTriggers(wantBackend);
|
|
203
208
|
const matchingBackend = backend.matchingBackend(wantBackend, (endpoint) => {
|
|
204
209
|
return (0, functionsDeployHelper_1.endpointMatchesAnyFilter)(endpoint, context.filters);
|
|
205
210
|
});
|
|
@@ -214,6 +219,41 @@ async function prepare(context, options, payload) {
|
|
|
214
219
|
validate.checkFiltersIntegrity(wantBackends, context.filters);
|
|
215
220
|
(0, applyHash_1.applyBackendHashToBackends)(wantBackends, context);
|
|
216
221
|
}
|
|
222
|
+
function moveEndpointToRegion(backend, endpoint, region) {
|
|
223
|
+
endpoint.region = region;
|
|
224
|
+
backend.endpoints[region] = backend.endpoints[region] || {};
|
|
225
|
+
backend.endpoints[region][endpoint.id] = endpoint;
|
|
226
|
+
delete backend.endpoints[build.REGION_TBD][endpoint.id];
|
|
227
|
+
if (Object.keys(backend.endpoints[build.REGION_TBD]).length === 0) {
|
|
228
|
+
delete backend.endpoints[build.REGION_TBD];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function matchRegionsForExisting(want, have) {
|
|
232
|
+
for (const [id, wantE] of Object.entries(want.endpoints[build.REGION_TBD] || {})) {
|
|
233
|
+
let matching;
|
|
234
|
+
for (const region of Object.keys(have.endpoints)) {
|
|
235
|
+
if (region === build.REGION_TBD) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (have.endpoints[region][id]) {
|
|
239
|
+
if (matching) {
|
|
240
|
+
throw new error_1.FirebaseError(`Cannot resolve default region for function ${id}. It exists in multiple regions. The region must be specified to continue.`);
|
|
241
|
+
}
|
|
242
|
+
matching = have.endpoints[region][id];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!matching) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
moveEndpointToRegion(want, wantE, matching.region);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
async function resolveDefaultRegions(want, have) {
|
|
252
|
+
matchRegionsForExisting(want, have);
|
|
253
|
+
for (const endpoint of Object.values(want.endpoints[build.REGION_TBD] || {})) {
|
|
254
|
+
moveEndpointToRegion(want, endpoint, "us-central1");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
217
257
|
function inferDetailsFromExisting(want, have, usedDotenv) {
|
|
218
258
|
for (const wantE of backend.allEndpoints(want)) {
|
|
219
259
|
const haveE = have.endpoints[wantE.region]?.[wantE.id];
|
|
@@ -347,6 +387,19 @@ async function loadCodebases(config, options, firebaseConfig, runtimeConfig, fil
|
|
|
347
387
|
}
|
|
348
388
|
return wantBuilds;
|
|
349
389
|
}
|
|
390
|
+
function warnIfDartBackendHasUnsupportedTriggers(want) {
|
|
391
|
+
const dartEndpoints = backend.allEndpoints(want).filter(triggerSupport_1.isDartEndpoint);
|
|
392
|
+
if (dartEndpoints.length === 0) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const { emulatorOnly, experimental } = (0, triggerSupport_1.classifyNonProductionEndpoints)(dartEndpoints);
|
|
396
|
+
const unsupported = [...emulatorOnly, ...experimental];
|
|
397
|
+
if (unsupported.length > 0) {
|
|
398
|
+
(0, utils_1.logLabeledWarning)("functions", `The following Dart functions use triggers that are not yet supported for production deployment: ${unsupported.map((ep) => ep.id).join(", ")}. ` +
|
|
399
|
+
"They will be deployed but may not work as expected. " +
|
|
400
|
+
"See https://github.com/firebase/firebase-functions-dart for current trigger support.");
|
|
401
|
+
}
|
|
402
|
+
}
|
|
350
403
|
async function warnIfNewGenkitFunctionIsMissingSecrets(have, want, options) {
|
|
351
404
|
if (options.force) {
|
|
352
405
|
return;
|