firebase-tools 13.17.0 → 13.19.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/README.md +10 -9
- package/lib/commands/dataconnect-services-list.js +4 -3
- package/lib/commands/dataconnect-sql-grant.js +37 -0
- package/lib/commands/dataconnect-sql-migrate.js +2 -1
- package/lib/commands/deploy.js +2 -0
- package/lib/commands/ext-info.js +3 -1
- package/lib/commands/ext-sdk-install.js +88 -0
- package/lib/commands/ext.js +1 -0
- package/lib/commands/index.js +3 -0
- package/lib/dataconnect/client.js +1 -1
- package/lib/dataconnect/dataplaneClient.js +1 -1
- package/lib/dataconnect/ensureApis.js +6 -1
- package/lib/dataconnect/load.js +3 -1
- package/lib/dataconnect/provisionCloudSql.js +34 -21
- package/lib/dataconnect/schemaMigration.js +126 -73
- package/lib/deploy/dataconnect/deploy.js +16 -13
- package/lib/deploy/dataconnect/prepare.js +36 -0
- package/lib/deploy/dataconnect/release.js +9 -2
- package/lib/deploy/extensions/deploymentSummary.js +3 -2
- package/lib/deploy/extensions/planner.js +32 -3
- package/lib/deploy/extensions/prepare.js +36 -64
- package/lib/deploy/extensions/release.js +11 -10
- package/lib/deploy/extensions/tasks.js +32 -21
- package/lib/deploy/firestore/prepare.js +10 -0
- package/lib/deploy/firestore/release.js +3 -6
- package/lib/deploy/functions/checkIam.js +7 -2
- package/lib/deploy/functions/ensure.js +10 -2
- package/lib/deploy/functions/prepare.js +10 -2
- package/lib/deploy/functions/runtimes/node/index.js +1 -1
- package/lib/deploy/index.js +9 -5
- package/lib/emulator/downloadableEmulators.js +9 -9
- package/lib/extensions/extensionsApi.js +3 -2
- package/lib/extensions/extensionsHelper.js +3 -3
- package/lib/extensions/localHelper.js +31 -0
- package/lib/extensions/runtimes/common.js +186 -38
- package/lib/extensions/runtimes/node.js +399 -0
- package/lib/extensions/types.js +10 -14
- package/lib/extensions/warnings.js +5 -2
- package/lib/firestore/checkDatabaseType.js +10 -3
- package/lib/frameworks/angular/index.js +15 -3
- package/lib/frameworks/next/utils.js +1 -1
- package/lib/gcp/cloudsql/permissions.js +6 -1
- package/lib/gcp/secretManager.js +12 -5
- package/lib/init/features/dataconnect/index.js +66 -53
- package/lib/init/features/firestore/index.js +20 -1
- package/lib/init/features/firestore/indexes.js +4 -4
- package/package.json +1 -1
- package/schema/connector-yaml.json +43 -17
- package/templates/init/dataconnect/connector.yaml +0 -1
- package/templates/init/dataconnect/dataconnect-fdccompatiblemode.yaml +12 -0
- package/templates/init/dataconnect/dataconnect.yaml +1 -1
package/README.md
CHANGED
|
@@ -117,15 +117,16 @@ Detailed doc is [here](https://firebase.google.com/docs/cli/auth).
|
|
|
117
117
|
|
|
118
118
|
### Extensions Commands
|
|
119
119
|
|
|
120
|
-
| Command
|
|
121
|
-
|
|
|
122
|
-
| **ext**
|
|
123
|
-
| **ext:configure**
|
|
124
|
-
| **ext:info**
|
|
125
|
-
| **ext:install**
|
|
126
|
-
| **ext:
|
|
127
|
-
| **ext:
|
|
128
|
-
| **ext:
|
|
120
|
+
| Command | Description |
|
|
121
|
+
| ------------------- | ------------------------------------------------------------------------------------------- |
|
|
122
|
+
| **ext** | Display information on how to use ext commands and extensions installed to your project. |
|
|
123
|
+
| **ext:configure** | Configure an existing extension instance. |
|
|
124
|
+
| **ext:info** | Display information about an extension by name (extensionName@x.y.z for a specific version) |
|
|
125
|
+
| **ext:install** | Install an extension. |
|
|
126
|
+
| **ext:sdk:install** | Install and SDK for an extension so you can define the extension in a functions codebase. |
|
|
127
|
+
| **ext:list** | List all the extensions that are installed in your Firebase project. |
|
|
128
|
+
| **ext:uninstall** | Uninstall an extension that is installed in your Firebase project by Instance ID. |
|
|
129
|
+
| **ext:update** | Update an existing extension instance to the latest version. |
|
|
129
130
|
|
|
130
131
|
### Cloud Firestore Commands
|
|
131
132
|
|
|
@@ -36,14 +36,15 @@ exports.command = new command_1.Command("dataconnect:services:list")
|
|
|
36
36
|
for (const service of services) {
|
|
37
37
|
const schema = (_a = (await client.getSchema(service.name))) !== null && _a !== void 0 ? _a : {
|
|
38
38
|
name: "",
|
|
39
|
-
|
|
39
|
+
datasources: [{}],
|
|
40
40
|
source: { files: [] },
|
|
41
41
|
};
|
|
42
42
|
const connectors = await client.listConnectors(service.name);
|
|
43
43
|
const serviceName = names.parseServiceName(service.name);
|
|
44
|
-
const
|
|
44
|
+
const postgresDatasource = schema === null || schema === void 0 ? void 0 : schema.datasources.find((d) => d.postgresql);
|
|
45
|
+
const instanceName = (_c = (_b = postgresDatasource === null || postgresDatasource === void 0 ? void 0 : postgresDatasource.postgresql) === null || _b === void 0 ? void 0 : _b.cloudSql.instance) !== null && _c !== void 0 ? _c : "";
|
|
45
46
|
const instanceId = instanceName.split("/").pop();
|
|
46
|
-
const dbId = (_e = (_d =
|
|
47
|
+
const dbId = (_e = (_d = postgresDatasource === null || postgresDatasource === void 0 ? void 0 : postgresDatasource.postgresql) === null || _d === void 0 ? void 0 : _d.database) !== null && _e !== void 0 ? _e : "";
|
|
47
48
|
const dbName = `CloudSQL Instance: ${instanceId}\nDatabase: ${dbId}`;
|
|
48
49
|
table.push([
|
|
49
50
|
serviceName.serviceId,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const command_1 = require("../command");
|
|
5
|
+
const projectUtils_1 = require("../projectUtils");
|
|
6
|
+
const ensureApis_1 = require("../dataconnect/ensureApis");
|
|
7
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
8
|
+
const fileUtils_1 = require("../dataconnect/fileUtils");
|
|
9
|
+
const schemaMigration_1 = require("../dataconnect/schemaMigration");
|
|
10
|
+
const requireAuth_1 = require("../requireAuth");
|
|
11
|
+
const error_1 = require("../error");
|
|
12
|
+
const permissions_1 = require("../gcp/cloudsql/permissions");
|
|
13
|
+
const allowedRoles = Object.keys(permissions_1.fdcSqlRoleMap);
|
|
14
|
+
exports.command = new command_1.Command("dataconnect:sql:grant [serviceId]")
|
|
15
|
+
.description("Grants the SQL role <role> to the provided user or service account <email>.")
|
|
16
|
+
.option("-R, --role <role>", "The SQL role to grant. One of: owner, writer, or reader.")
|
|
17
|
+
.option("-E, --email <email>", "The email of the user or service account we would like to grant the role to.")
|
|
18
|
+
.before(requirePermissions_1.requirePermissions, ["firebasedataconnect.services.list"])
|
|
19
|
+
.before(requireAuth_1.requireAuth)
|
|
20
|
+
.action(async (serviceId, options) => {
|
|
21
|
+
const role = options.role;
|
|
22
|
+
const email = options.email;
|
|
23
|
+
if (!role) {
|
|
24
|
+
throw new error_1.FirebaseError("-R, --role <role> is required. Run the command with -h for more info.");
|
|
25
|
+
}
|
|
26
|
+
if (!email) {
|
|
27
|
+
throw new error_1.FirebaseError("-E, --email <email> is required. Run the command with -h for more info.");
|
|
28
|
+
}
|
|
29
|
+
if (!allowedRoles.includes(role.toLowerCase())) {
|
|
30
|
+
throw new error_1.FirebaseError(`Role should be one of ${allowedRoles.join(" | ")}.`);
|
|
31
|
+
}
|
|
32
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
33
|
+
await (0, ensureApis_1.ensureApis)(projectId);
|
|
34
|
+
const serviceInfo = await (0, fileUtils_1.pickService)(projectId, options.config, serviceId);
|
|
35
|
+
await (0, schemaMigration_1.grantRoleToUserInSchema)(options, serviceInfo.schema);
|
|
36
|
+
return { projectId, serviceId };
|
|
37
|
+
});
|
|
@@ -21,7 +21,7 @@ exports.command = new command_1.Command("dataconnect:sql:migrate [serviceId]")
|
|
|
21
21
|
.before(requireAuth_1.requireAuth)
|
|
22
22
|
.withForce("Execute any required database changes without prompting")
|
|
23
23
|
.action(async (serviceId, options) => {
|
|
24
|
-
var _a;
|
|
24
|
+
var _a, _b;
|
|
25
25
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
26
26
|
await (0, ensureApis_1.ensureApis)(projectId);
|
|
27
27
|
const serviceInfo = await (0, fileUtils_1.pickService)(projectId, options.config, serviceId);
|
|
@@ -33,6 +33,7 @@ exports.command = new command_1.Command("dataconnect:sql:migrate [serviceId]")
|
|
|
33
33
|
options,
|
|
34
34
|
schema: serviceInfo.schema,
|
|
35
35
|
validateOnly: true,
|
|
36
|
+
schemaValidation: (_b = serviceInfo.dataConnectYaml.schema.datasource.postgresql) === null || _b === void 0 ? void 0 : _b.schemaValidation,
|
|
36
37
|
});
|
|
37
38
|
if (diffs.length) {
|
|
38
39
|
(0, utils_1.logLabeledSuccess)("dataconnect", `Database schema sucessfully migrated! Run 'firebase deploy' to deploy your new schema to your Data Connect service.`);
|
package/lib/commands/deploy.js
CHANGED
|
@@ -86,6 +86,8 @@ exports.command = new command_1.Command("deploy")
|
|
|
86
86
|
"For data connect, can specify filters with colons to deploy only a service, connector, or schema" +
|
|
87
87
|
'(e.g. "--only dataconnect:serviceId,dataconnect:serviceId:connectorId,dataconnect:serviceId:schema"). ')
|
|
88
88
|
.option("--except <targets>", 'deploy to all targets except specified (e.g. "database")')
|
|
89
|
+
.option("--dry-run", "Perform a dry run of your deployment. Validates your changes and builds your code without deploying any changes to your project. " +
|
|
90
|
+
"In order to provide better validation, this may still enable APIs on the target project.")
|
|
89
91
|
.before(requireConfig_1.requireConfig)
|
|
90
92
|
.before((options) => {
|
|
91
93
|
options.filteredTargets = (0, filterTargets_1.filterTargets)(options, exports.VALID_DEPLOY_TARGETS);
|
package/lib/commands/ext-info.js
CHANGED
|
@@ -110,7 +110,9 @@ exports.command = new command_1.Command("ext:info <extensionName>")
|
|
|
110
110
|
else {
|
|
111
111
|
marked_1.marked.use((0, marked_terminal_1.markedTerminal)());
|
|
112
112
|
logger_1.logger.info(await (0, marked_1.marked)(lines.join("\n")));
|
|
113
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `to install this extension,
|
|
113
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `to install this extension, run ` +
|
|
114
114
|
clc.bold(`firebase ext:install ${extensionName} --project=YOUR_PROJECT`));
|
|
115
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `to install an autogenerated SDK for this extension into your functions codebase, run ` +
|
|
116
|
+
clc.bold(`firebase ext:sdk:install ${extensionName} --project=YOUR_PROJECT`));
|
|
115
117
|
}
|
|
116
118
|
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const clc = require("colorette");
|
|
5
|
+
const semver = require("semver");
|
|
6
|
+
const checkMinRequiredVersion_1 = require("../checkMinRequiredVersion");
|
|
7
|
+
const command_1 = require("../command");
|
|
8
|
+
const extensionsApi = require("../extensions/extensionsApi");
|
|
9
|
+
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
10
|
+
const localHelper_1 = require("../extensions/localHelper");
|
|
11
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
12
|
+
const common_1 = require("../extensions/runtimes/common");
|
|
13
|
+
const error_1 = require("../error");
|
|
14
|
+
const displayExtensionInfo_1 = require("../extensions/displayExtensionInfo");
|
|
15
|
+
const refs = require("../extensions/refs");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
const prompt_1 = require("../prompt");
|
|
18
|
+
const utils = require("../utils");
|
|
19
|
+
exports.command = new command_1.Command("ext:sdk:install <extensionName>")
|
|
20
|
+
.description("get an SDK for this extension. The SDK will be put in the 'generated' directory")
|
|
21
|
+
.option(`--codebase <codebase>`, `specifies a codebase to install the SDK into`)
|
|
22
|
+
.option(`--force`, `will overwrite existing sdk files if true`)
|
|
23
|
+
.before(checkMinRequiredVersion_1.checkMinRequiredVersion, "extDevMinVersion")
|
|
24
|
+
.action(async (extensionName, options) => {
|
|
25
|
+
const runtime = await (0, common_1.getCodebaseRuntime)(options);
|
|
26
|
+
if (!runtime.startsWith("nodejs")) {
|
|
27
|
+
throw new error_1.FirebaseError(`Extension SDK generation is currently only supported for NodeJs. We detected the target source to be: ${runtime}`);
|
|
28
|
+
}
|
|
29
|
+
let spec;
|
|
30
|
+
let extensionRef;
|
|
31
|
+
let localPath;
|
|
32
|
+
if ((0, localHelper_1.isLocalExtension)(extensionName)) {
|
|
33
|
+
spec = await (0, localHelper_1.getLocalExtensionSpec)(extensionName);
|
|
34
|
+
spec.systemParams = [];
|
|
35
|
+
localPath = extensionName;
|
|
36
|
+
await (0, displayExtensionInfo_1.displayExtensionVersionInfo)({ spec });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
await (0, requirePermissions_1.requirePermissions)(options, ["firebaseextensions.sources.get"]);
|
|
40
|
+
await (0, extensionsHelper_1.ensureExtensionsApiEnabled)(options);
|
|
41
|
+
const hasPublisherId = extensionName.split("/").length >= 2;
|
|
42
|
+
if (hasPublisherId) {
|
|
43
|
+
const nameAndVersion = extensionName.split("/")[1];
|
|
44
|
+
if (nameAndVersion.split("@").length < 2) {
|
|
45
|
+
extensionName = extensionName + "@latest";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const [name, version] = extensionName.split("@");
|
|
50
|
+
extensionName = `firebase/${name}@${version || "latest"}`;
|
|
51
|
+
}
|
|
52
|
+
const ref = refs.parse(extensionName);
|
|
53
|
+
const extension = await extensionsApi.getExtension(refs.toExtensionRef(ref));
|
|
54
|
+
const version = await extensionsApi.getExtensionVersion(extensionName);
|
|
55
|
+
spec = version.spec;
|
|
56
|
+
extensionRef = version.ref;
|
|
57
|
+
await (0, displayExtensionInfo_1.displayExtensionVersionInfo)({
|
|
58
|
+
spec,
|
|
59
|
+
extensionVersion: version,
|
|
60
|
+
latestApprovedVersion: extension.latestApprovedVersion,
|
|
61
|
+
latestVersion: extension.latestVersion,
|
|
62
|
+
});
|
|
63
|
+
if (version.state === "DEPRECATED") {
|
|
64
|
+
throw new error_1.FirebaseError(`Extension version ${clc.bold(extensionName)} is deprecated and cannot be installed. To install an SDK for the ` +
|
|
65
|
+
`latest non-deprecated version, omit the version in the extension ref.`);
|
|
66
|
+
}
|
|
67
|
+
logger_1.logger.info();
|
|
68
|
+
if ((extension.latestApprovedVersion &&
|
|
69
|
+
semver.gt(extension.latestApprovedVersion, version.spec.version)) ||
|
|
70
|
+
(!extension.latestApprovedVersion &&
|
|
71
|
+
extension.latestVersion &&
|
|
72
|
+
semver.gt(extension.latestVersion, version.spec.version))) {
|
|
73
|
+
const latest = extension.latestApprovedVersion || extension.latestVersion;
|
|
74
|
+
logger_1.logger.info(`You are about to install an SDK for extension version ${clc.bold(version.spec.version)} which is older than the latest ${extension.latestApprovedVersion ? "accepted version" : "version"} ${clc.bold(latest)}.`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!(await (0, prompt_1.confirm)({
|
|
78
|
+
nonInteractive: options.nonInteractive,
|
|
79
|
+
force: options.force,
|
|
80
|
+
default: true,
|
|
81
|
+
}))) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const codeSample = await (0, common_1.writeSDK)(extensionRef, localPath, spec, options);
|
|
85
|
+
logger_1.logger.info();
|
|
86
|
+
utils.logSuccess("Extension SDK installed successfully");
|
|
87
|
+
logger_1.logger.info(codeSample);
|
|
88
|
+
});
|
package/lib/commands/ext.js
CHANGED
package/lib/commands/index.js
CHANGED
|
@@ -83,6 +83,8 @@ function load(client) {
|
|
|
83
83
|
client.ext.list = loadCommand("ext-list");
|
|
84
84
|
client.ext.uninstall = loadCommand("ext-uninstall");
|
|
85
85
|
client.ext.update = loadCommand("ext-update");
|
|
86
|
+
client.ext.sdk = {};
|
|
87
|
+
client.ext.sdk.install = loadCommand("ext-sdk-install");
|
|
86
88
|
client.ext.dev = {};
|
|
87
89
|
client.ext.dev.init = loadCommand("ext-dev-init");
|
|
88
90
|
client.ext.dev.list = loadCommand("ext-dev-list");
|
|
@@ -207,6 +209,7 @@ function load(client) {
|
|
|
207
209
|
client.dataconnect.sql = {};
|
|
208
210
|
client.dataconnect.sql.diff = loadCommand("dataconnect-sql-diff");
|
|
209
211
|
client.dataconnect.sql.migrate = loadCommand("dataconnect-sql-migrate");
|
|
212
|
+
client.dataconnect.sql.grant = loadCommand("dataconnect-sql-grant");
|
|
210
213
|
client.dataconnect.sdk = {};
|
|
211
214
|
client.dataconnect.sdk.generate = loadCommand("dataconnect-sdk-generate");
|
|
212
215
|
client.target = loadCommand("target");
|
|
@@ -5,7 +5,7 @@ const api_1 = require("../api");
|
|
|
5
5
|
const apiv2_1 = require("../apiv2");
|
|
6
6
|
const operationPoller = require("../operation-poller");
|
|
7
7
|
const types = require("./types");
|
|
8
|
-
const DATACONNECT_API_VERSION = "
|
|
8
|
+
const DATACONNECT_API_VERSION = "v1beta";
|
|
9
9
|
const PAGE_SIZE_MAX = 100;
|
|
10
10
|
const dataconnectClient = () => new apiv2_1.Client({
|
|
11
11
|
urlPrefix: (0, api_1.dataconnectOrigin)(),
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.executeGraphQL = void 0;
|
|
4
4
|
const api_1 = require("../api");
|
|
5
5
|
const apiv2_1 = require("../apiv2");
|
|
6
|
-
const DATACONNECT_API_VERSION = "
|
|
6
|
+
const DATACONNECT_API_VERSION = "v1beta";
|
|
7
7
|
const dataconnectDataplaneClient = () => new apiv2_1.Client({
|
|
8
8
|
urlPrefix: (0, api_1.dataconnectOrigin)(),
|
|
9
9
|
apiVersion: DATACONNECT_API_VERSION,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureApis = void 0;
|
|
3
|
+
exports.ensureSparkApis = exports.ensureApis = void 0;
|
|
4
4
|
const api = require("../api");
|
|
5
5
|
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
6
6
|
async function ensureApis(projectId) {
|
|
@@ -10,3 +10,8 @@ async function ensureApis(projectId) {
|
|
|
10
10
|
await (0, ensureApiEnabled_1.ensure)(projectId, api.computeOrigin(), prefix);
|
|
11
11
|
}
|
|
12
12
|
exports.ensureApis = ensureApis;
|
|
13
|
+
async function ensureSparkApis(projectId) {
|
|
14
|
+
const prefix = "dataconnect";
|
|
15
|
+
await (0, ensureApiEnabled_1.ensure)(projectId, api.cloudSQLAdminOrigin(), prefix);
|
|
16
|
+
}
|
|
17
|
+
exports.ensureSparkApis = ensureSparkApis;
|
package/lib/dataconnect/load.js
CHANGED
|
@@ -30,7 +30,9 @@ async function load(projectId, config, sourceDirectory) {
|
|
|
30
30
|
sourceDirectory: resolvedDir,
|
|
31
31
|
schema: {
|
|
32
32
|
name: `${serviceName}/schemas/${types_1.SCHEMA_ID}`,
|
|
33
|
-
|
|
33
|
+
datasources: [
|
|
34
|
+
(0, types_1.toDatasource)(projectId, dataConnectYaml.location, dataConnectYaml.schema.datasource),
|
|
35
|
+
],
|
|
34
36
|
source: {
|
|
35
37
|
files: schemaGQLs,
|
|
36
38
|
},
|
|
@@ -11,19 +11,22 @@ const freeTrial_1 = require("./freeTrial");
|
|
|
11
11
|
const error_1 = require("../error");
|
|
12
12
|
async function provisionCloudSql(args) {
|
|
13
13
|
let connectionName = "";
|
|
14
|
-
const { projectId, locationId, instanceId, databaseId, enableGoogleMlIntegration, waitForCreation, silent, } = args;
|
|
14
|
+
const { projectId, locationId, instanceId, databaseId, enableGoogleMlIntegration, waitForCreation, silent, dryRun, } = args;
|
|
15
15
|
try {
|
|
16
16
|
const existingInstance = await cloudSqlAdminClient.getInstance(projectId, instanceId);
|
|
17
17
|
silent || utils.logLabeledBullet("dataconnect", `Found existing instance ${instanceId}.`);
|
|
18
18
|
connectionName = (existingInstance === null || existingInstance === void 0 ? void 0 : existingInstance.connectionName) || "";
|
|
19
19
|
const why = getUpdateReason(existingInstance, enableGoogleMlIntegration);
|
|
20
20
|
if (why) {
|
|
21
|
+
const cta = dryRun
|
|
22
|
+
? `It will be updated on your next deploy.`
|
|
23
|
+
: `Updating instance. This may take a few minutes...`;
|
|
21
24
|
silent ||
|
|
22
|
-
utils.logLabeledBullet("dataconnect", `Instance ${instanceId} settings not compatible with Firebase Data Connect. ` +
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
utils.logLabeledBullet("dataconnect", `Instance ${instanceId} settings not compatible with Firebase Data Connect. ` + cta + why);
|
|
26
|
+
if (!dryRun) {
|
|
27
|
+
await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.updateInstanceForDataConnect(existingInstance, enableGoogleMlIntegration), "Updating your instance...");
|
|
28
|
+
silent || utils.logLabeledBullet("dataconnect", "Instance updated");
|
|
29
|
+
}
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
catch (err) {
|
|
@@ -35,19 +38,23 @@ async function provisionCloudSql(args) {
|
|
|
35
38
|
(0, freeTrial_1.printFreeTrialUnavailable)(projectId, freeTrialInstanceId);
|
|
36
39
|
throw new error_1.FirebaseError("Free trial unavailable.");
|
|
37
40
|
}
|
|
41
|
+
const cta = dryRun ? "It will be created on your next deploy" : "Creating it now.";
|
|
38
42
|
silent ||
|
|
39
|
-
utils.logLabeledBullet("dataconnect", `CloudSQL instance '${instanceId}' not found
|
|
43
|
+
utils.logLabeledBullet("dataconnect", `CloudSQL instance '${instanceId}' not found.` +
|
|
44
|
+
cta +
|
|
40
45
|
`\nThis instance is provided under the terms of the Data Connect free trial ${(0, freeTrial_1.freeTrialTermsLink)()}` +
|
|
41
46
|
`\nMonitor the progress at ${cloudSqlAdminClient.instanceConsoleLink(projectId, instanceId)}`);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
if (!dryRun) {
|
|
48
|
+
const newInstance = await (0, utils_1.promiseWithSpinner)(() => cloudSqlAdminClient.createInstance(projectId, locationId, instanceId, enableGoogleMlIntegration, waitForCreation), "Creating your instance...");
|
|
49
|
+
if (newInstance) {
|
|
50
|
+
silent || utils.logLabeledBullet("dataconnect", "Instance created");
|
|
51
|
+
connectionName = (newInstance === null || newInstance === void 0 ? void 0 : newInstance.connectionName) || "";
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
silent ||
|
|
55
|
+
utils.logLabeledBullet("dataconnect", "Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy.");
|
|
56
|
+
return connectionName;
|
|
57
|
+
}
|
|
51
58
|
}
|
|
52
59
|
}
|
|
53
60
|
try {
|
|
@@ -56,17 +63,23 @@ async function provisionCloudSql(args) {
|
|
|
56
63
|
}
|
|
57
64
|
catch (err) {
|
|
58
65
|
if (err.status === 404) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
if (dryRun) {
|
|
67
|
+
silent ||
|
|
68
|
+
utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found. It will be created on your next deploy.`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
silent ||
|
|
72
|
+
utils.logLabeledBullet("dataconnect", `Database ${databaseId} not found, creating it now...`);
|
|
73
|
+
await cloudSqlAdminClient.createDatabase(projectId, instanceId, databaseId);
|
|
74
|
+
silent || utils.logLabeledBullet("dataconnect", `Database ${databaseId} created.`);
|
|
75
|
+
}
|
|
63
76
|
}
|
|
64
77
|
else {
|
|
65
78
|
logger_1.logger.debug(`Unexpected error from CloudSQL: ${err}`);
|
|
66
79
|
silent || utils.logLabeledWarning("dataconnect", `Database ${databaseId} is not accessible.`);
|
|
67
80
|
}
|
|
68
81
|
}
|
|
69
|
-
if (enableGoogleMlIntegration) {
|
|
82
|
+
if (enableGoogleMlIntegration && !dryRun) {
|
|
70
83
|
await (0, checkIam_1.grantRolesToCloudSqlServiceAccount)(projectId, instanceId, [GOOGLE_ML_INTEGRATION_ROLE]);
|
|
71
84
|
}
|
|
72
85
|
return connectionName;
|