firebase-tools 13.20.1 → 13.21.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/apphosting/githubConnections.js +19 -1
- package/lib/apphosting/index.js +12 -46
- package/lib/apphosting/rollout.js +127 -0
- package/lib/command.js +10 -3
- package/lib/commands/apphosting-rollouts-create.js +13 -13
- package/lib/commands/emulators-start.js +1 -1
- package/lib/config.js +14 -4
- package/lib/dataconnect/fileUtils.js +7 -43
- package/lib/dataconnect/freeTrial.js +44 -10
- package/lib/dataconnect/provisionCloudSql.js +4 -4
- package/lib/dataconnect/types.js +3 -2
- package/lib/dataconnect/webhook.js +2 -1
- package/lib/deploy/dataconnect/prepare.js +5 -0
- package/lib/emulator/apphosting/config.js +45 -0
- package/lib/emulator/apphosting/index.js +9 -11
- package/lib/emulator/apphosting/serve.js +16 -10
- package/lib/emulator/apphosting/utils.js +18 -0
- package/lib/emulator/controller.js +6 -1
- package/lib/emulator/downloadableEmulators.js +12 -12
- package/lib/emulator/eventarcEmulator.js +1 -1
- package/lib/emulator/extensionsEmulator.js +38 -6
- package/lib/emulator/functionsEmulator.js +85 -41
- package/lib/emulator/functionsEmulatorShared.js +2 -1
- package/lib/error.js +24 -1
- package/lib/extensions/emulator/triggerHelper.js +1 -1
- package/lib/extensions/extensionsApi.js +11 -8
- package/lib/extensions/runtimes/common.js +11 -19
- package/lib/extensions/runtimes/node.js +25 -22
- package/lib/extensions/types.js +16 -1
- package/lib/gcp/cloudmonitoring.js +3 -3
- package/lib/gcp/cloudsql/cloudsqladmin.js +32 -20
- package/lib/gcp/devConnect.js +38 -1
- package/lib/init/features/dataconnect/index.js +69 -85
- package/lib/init/features/dataconnect/sdk.js +69 -86
- package/lib/init/spawn.js +2 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.longestCommonPrefix = exports.snakeToCamelCase = exports.lowercaseFirstLetter = exports.capitalizeFirstLetter = exports.toTitleCase = exports.getInstallPathPrefix = exports.getCodebaseDir = exports.writeSDK = exports.getCodebaseRuntime = exports.copyDirectory = exports.writeFile = exports.isTypescriptCodebase = exports.extensionMatchesAnyFilter = exports.extractExtensionsFromBuilds = exports.
|
|
3
|
+
exports.longestCommonPrefix = exports.snakeToCamelCase = exports.lowercaseFirstLetter = exports.capitalizeFirstLetter = exports.toTitleCase = exports.getInstallPathPrefix = exports.getCodebaseDir = exports.writeSDK = exports.getCodebaseRuntime = exports.copyDirectory = exports.writeFile = exports.isTypescriptCodebase = exports.extensionMatchesAnyFilter = exports.extractExtensionsFromBuilds = exports.fixDarkBlueText = void 0;
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const prompt_1 = require("../../prompt");
|
|
@@ -8,7 +8,6 @@ const fsutils = require("../../fsutils");
|
|
|
8
8
|
const utils_1 = require("../../utils");
|
|
9
9
|
const error_1 = require("../../error");
|
|
10
10
|
const projectConfig_1 = require("../../functions/projectConfig");
|
|
11
|
-
const types_1 = require("../types");
|
|
12
11
|
const functionRuntimes = require("../../deploy/functions/runtimes");
|
|
13
12
|
const nodeRuntime = require("./node");
|
|
14
13
|
function fixDarkBlueText(txt) {
|
|
@@ -17,15 +16,6 @@ function fixDarkBlueText(txt) {
|
|
|
17
16
|
return txt.replaceAll(DARK_BLUE, BRIGHT_CYAN);
|
|
18
17
|
}
|
|
19
18
|
exports.fixDarkBlueText = fixDarkBlueText;
|
|
20
|
-
function getErrorMessage(err, defaultMsg) {
|
|
21
|
-
if ((0, types_1.isObject)(err) && err.message && typeof err.message === "string") {
|
|
22
|
-
return err.message;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
return defaultMsg;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.getErrorMessage = getErrorMessage;
|
|
29
19
|
function extractExtensionsFromBuilds(builds, filters) {
|
|
30
20
|
const extRecords = {};
|
|
31
21
|
for (const [codebase, build] of Object.entries(builds)) {
|
|
@@ -80,7 +70,7 @@ async function writeFile(filePath, data, options) {
|
|
|
80
70
|
(0, utils_1.logLabeledBullet)("extensions", `successfully wrote ${shortFilePath}`);
|
|
81
71
|
}
|
|
82
72
|
catch (err) {
|
|
83
|
-
throw new error_1.FirebaseError(`Failed to write ${shortFilePath}:\n ${err}`);
|
|
73
|
+
throw new error_1.FirebaseError(`Failed to write ${shortFilePath}:\n ${(0, error_1.getErrMsg)(err)}`);
|
|
84
74
|
}
|
|
85
75
|
}
|
|
86
76
|
else {
|
|
@@ -95,11 +85,11 @@ async function writeFile(filePath, data, options) {
|
|
|
95
85
|
(0, utils_1.logLabeledBullet)("extensions", `successfully created ${shortFilePath}`);
|
|
96
86
|
}
|
|
97
87
|
catch (err) {
|
|
98
|
-
throw new error_1.FirebaseError(`Failed to create ${shortFilePath}:\n ${err}`);
|
|
88
|
+
throw new error_1.FirebaseError(`Failed to create ${shortFilePath}:\n ${(0, error_1.getErrMsg)(err)}`);
|
|
99
89
|
}
|
|
100
90
|
}
|
|
101
91
|
catch (err) {
|
|
102
|
-
throw new error_1.FirebaseError(`Error during SDK file creation:\n ${err}`);
|
|
92
|
+
throw new error_1.FirebaseError(`Error during SDK file creation:\n ${(0, error_1.getErrMsg)(err)}`);
|
|
103
93
|
}
|
|
104
94
|
}
|
|
105
95
|
}
|
|
@@ -121,14 +111,14 @@ async function copyDirectory(src, dest, options) {
|
|
|
121
111
|
if (srcPath.includes("node_modules")) {
|
|
122
112
|
continue;
|
|
123
113
|
}
|
|
124
|
-
await copyDirectory(srcPath, destPath, { force: true });
|
|
114
|
+
await copyDirectory(srcPath, destPath, Object.assign(Object.assign({}, options), { force: true }));
|
|
125
115
|
}
|
|
126
116
|
else if (entry.isFile())
|
|
127
117
|
try {
|
|
128
118
|
await fs.promises.copyFile(srcPath, destPath);
|
|
129
119
|
}
|
|
130
120
|
catch (err) {
|
|
131
|
-
throw new error_1.FirebaseError(`Failed to copy ${destPath.replace(process.cwd(), ".")}:\n ${err}`);
|
|
121
|
+
throw new error_1.FirebaseError(`Failed to copy ${destPath.replace(process.cwd(), ".")}:\n ${(0, error_1.getErrMsg)(err)}`);
|
|
132
122
|
}
|
|
133
123
|
}
|
|
134
124
|
}
|
|
@@ -137,9 +127,8 @@ async function copyDirectory(src, dest, options) {
|
|
|
137
127
|
}
|
|
138
128
|
}
|
|
139
129
|
else {
|
|
140
|
-
await fs.promises.mkdir(dest, { recursive: true })
|
|
141
|
-
|
|
142
|
-
});
|
|
130
|
+
await fs.promises.mkdir(dest, { recursive: true });
|
|
131
|
+
await copyDirectory(src, dest, Object.assign(Object.assign({}, options), { force: true }));
|
|
143
132
|
}
|
|
144
133
|
}
|
|
145
134
|
exports.copyDirectory = copyDirectory;
|
|
@@ -177,6 +166,9 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
177
166
|
}
|
|
178
167
|
exports.writeSDK = writeSDK;
|
|
179
168
|
function getCodebaseDir(options) {
|
|
169
|
+
if (!options.projectRoot) {
|
|
170
|
+
throw new error_1.FirebaseError("Unable to determine root directory of project");
|
|
171
|
+
}
|
|
180
172
|
const config = (0, projectConfig_1.normalizeAndValidate)(options.config.src.functions);
|
|
181
173
|
const codebaseConfig = (0, projectConfig_1.configForCodebase)(config, options.codebase || projectConfig_1.DEFAULT_CODEBASE);
|
|
182
174
|
return `${options.projectRoot}/${codebaseConfig.source}/`;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.writeSDK = exports.TYPESCRIPT_VERSION = exports.FIREBASE_FUNCTIONS_VERSION = exports.SDK_GENERATION_VERSION = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const marked_terminal_1 = require("marked-terminal");
|
|
7
|
+
const marked_1 = require("marked");
|
|
4
8
|
const types_1 = require("../types");
|
|
5
9
|
const prompt_1 = require("../../prompt");
|
|
6
10
|
const secretsUtils = require("../secretsUtils");
|
|
7
|
-
const child_process_1 = require("child_process");
|
|
8
11
|
const utils_1 = require("../../utils");
|
|
9
|
-
const path = require("path");
|
|
10
12
|
const common_1 = require("./common");
|
|
11
13
|
const askUserForEventsConfig_1 = require("../askUserForEventsConfig");
|
|
12
14
|
const extensionsHelper_1 = require("../extensionsHelper");
|
|
13
15
|
const error_1 = require("../../error");
|
|
14
|
-
const marked_terminal_1 = require("marked-terminal");
|
|
15
|
-
const marked_1 = require("marked");
|
|
16
16
|
marked_1.marked.use((0, marked_terminal_1.markedTerminal)());
|
|
17
17
|
exports.SDK_GENERATION_VERSION = "1.0.0";
|
|
18
18
|
exports.FIREBASE_FUNCTIONS_VERSION = ">=5.1.0";
|
|
@@ -67,7 +67,7 @@ function makeClassName(name) {
|
|
|
67
67
|
function makeEventName(name, prefix) {
|
|
68
68
|
let eventName;
|
|
69
69
|
const versionedEvent = /^(?:[^.]+[.])+(?:[vV]\d+[.])(?<event>.*)$/;
|
|
70
|
-
const match =
|
|
70
|
+
const match = versionedEvent.exec(name);
|
|
71
71
|
if (match) {
|
|
72
72
|
eventName = match[1];
|
|
73
73
|
}
|
|
@@ -79,7 +79,7 @@ function makeEventName(name, prefix) {
|
|
|
79
79
|
eventName = parts[parts.length - 1];
|
|
80
80
|
}
|
|
81
81
|
const allCaps = /^[A-Z._-]+$/;
|
|
82
|
-
eventName =
|
|
82
|
+
eventName = allCaps.exec(eventName) ? eventName : eventName.replace(/([A-Z])/g, " $1").trim();
|
|
83
83
|
eventName = eventName.replace(/[._-]/g, " ");
|
|
84
84
|
eventName = eventName.toLowerCase().startsWith("on") ? eventName : "on " + eventName;
|
|
85
85
|
eventName = eventName.replace(/\w\S*/g, common_1.toTitleCase);
|
|
@@ -87,6 +87,15 @@ function makeEventName(name, prefix) {
|
|
|
87
87
|
eventName = eventName.charAt(0).toLowerCase() + eventName.substring(1);
|
|
88
88
|
return eventName;
|
|
89
89
|
}
|
|
90
|
+
function addPeerDependency(pkgJson, dependency, version) {
|
|
91
|
+
if (!pkgJson.peerDependencies) {
|
|
92
|
+
pkgJson.peerDependencies = {};
|
|
93
|
+
}
|
|
94
|
+
if (!(0, types_1.isObject)(pkgJson.peerDependencies)) {
|
|
95
|
+
throw new error_1.FirebaseError("Internal error generating peer dependencies.");
|
|
96
|
+
}
|
|
97
|
+
pkgJson.peerDependencies[dependency] = version;
|
|
98
|
+
}
|
|
90
99
|
async function writeSDK(extensionRef, localPath, spec, options) {
|
|
91
100
|
var _a, _b, _c;
|
|
92
101
|
const sdkLines = [];
|
|
@@ -105,7 +114,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
105
114
|
})) {
|
|
106
115
|
const newLocalPath = path.join(dirPath, "src");
|
|
107
116
|
await (0, common_1.copyDirectory)(localPath, newLocalPath, options);
|
|
108
|
-
localPath = newLocalPath.replace(options.projectRoot, ".");
|
|
117
|
+
localPath = newLocalPath.replace(options.projectRoot || ".", ".");
|
|
109
118
|
}
|
|
110
119
|
}
|
|
111
120
|
if (!dirPath) {
|
|
@@ -115,7 +124,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
115
124
|
const pkgJson = {
|
|
116
125
|
name: packageName,
|
|
117
126
|
version: `${exports.SDK_GENERATION_VERSION}`,
|
|
118
|
-
description: `Generated SDK for ${spec.displayName}@${spec.version}`,
|
|
127
|
+
description: `Generated SDK for ${spec.displayName || spec.name}@${spec.version}`,
|
|
119
128
|
main: "./output/index.js",
|
|
120
129
|
private: true,
|
|
121
130
|
scripts: {
|
|
@@ -138,7 +147,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
138
147
|
},
|
|
139
148
|
};
|
|
140
149
|
sdkLines.push("/**");
|
|
141
|
-
sdkLines.push(` * ${spec.displayName} SDK for ${spec.name}@${spec.version}`);
|
|
150
|
+
sdkLines.push(` * ${spec.displayName || spec.name} SDK for ${spec.name}@${spec.version}`);
|
|
142
151
|
sdkLines.push(" *");
|
|
143
152
|
sdkLines.push(" * When filing bugs or feature requests please specify:");
|
|
144
153
|
if (extensionRef) {
|
|
@@ -155,18 +164,12 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
155
164
|
if (hasEvents) {
|
|
156
165
|
sdkLines.push(`import { CloudEvent } from "firebase-functions/v2";`);
|
|
157
166
|
sdkLines.push(`import { onCustomEventPublished, EventarcTriggerOptions } from "firebase-functions/v2/eventarc";`);
|
|
158
|
-
|
|
159
|
-
pkgJson.peerDependencies = {};
|
|
160
|
-
}
|
|
161
|
-
pkgJson.peerDependencies["firebase-functions"] = exports.FIREBASE_FUNCTIONS_VERSION;
|
|
167
|
+
addPeerDependency(pkgJson, "firebase-functions", exports.FIREBASE_FUNCTIONS_VERSION);
|
|
162
168
|
}
|
|
163
169
|
const usesSecrets = secretsUtils.usesSecrets(spec);
|
|
164
170
|
if (usesSecrets) {
|
|
165
171
|
sdkLines.push(`import { defineSecret } from "firebase-functions/params";`);
|
|
166
|
-
|
|
167
|
-
pkgJson.peerDependencies = {};
|
|
168
|
-
}
|
|
169
|
-
pkgJson.peerDependencies["firebase-functions"] = exports.FIREBASE_FUNCTIONS_VERSION;
|
|
172
|
+
addPeerDependency(pkgJson, "firebase-functions", exports.FIREBASE_FUNCTIONS_VERSION);
|
|
170
173
|
}
|
|
171
174
|
if (hasEvents || usesSecrets) {
|
|
172
175
|
sdkLines.push("");
|
|
@@ -289,7 +292,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
289
292
|
sdkLines.push(` ${sysParam.param}${opt}: string;`);
|
|
290
293
|
break;
|
|
291
294
|
default:
|
|
292
|
-
throw new error_1.FirebaseError(`Error: Unknown systemParam type: ${sysParam.type}.`);
|
|
295
|
+
throw new error_1.FirebaseError(`Error: Unknown systemParam type: ${sysParam.type || "undefined"}.`);
|
|
293
296
|
}
|
|
294
297
|
sdkLines.push("");
|
|
295
298
|
}
|
|
@@ -299,7 +302,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
299
302
|
sdkLines.push(` return new ${className}(instanceId, params);`);
|
|
300
303
|
sdkLines.push("}\n");
|
|
301
304
|
sdkLines.push(`/**`);
|
|
302
|
-
sdkLines.push(` * ${spec.displayName}`);
|
|
305
|
+
sdkLines.push(` * ${spec.displayName || spec.name}`);
|
|
303
306
|
(_c = spec.description) === null || _c === void 0 ? void 0 : _c.split("\n").forEach((val) => {
|
|
304
307
|
sdkLines.push(` * ${val.replace(/\*\//g, "* /")}`);
|
|
305
308
|
});
|
|
@@ -347,7 +350,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
347
350
|
(0, child_process_1.execFileSync)("npm", ["--prefix", dirPath, "install"]);
|
|
348
351
|
}
|
|
349
352
|
catch (err) {
|
|
350
|
-
const errMsg = (0,
|
|
353
|
+
const errMsg = (0, error_1.getErrMsg)(err, "unknown error");
|
|
351
354
|
throw new error_1.FirebaseError(`Error during npm install in ${shortDirPath}: ${errMsg}`);
|
|
352
355
|
}
|
|
353
356
|
(0, utils_1.logLabeledBullet)("extensions", `running 'npm --prefix ${shortDirPath} run build'`);
|
|
@@ -355,7 +358,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
355
358
|
(0, child_process_1.execFileSync)("npm", ["--prefix", dirPath, "run", "build"]);
|
|
356
359
|
}
|
|
357
360
|
catch (err) {
|
|
358
|
-
const errMsg = (0,
|
|
361
|
+
const errMsg = (0, error_1.getErrMsg)(err, "unknown error");
|
|
359
362
|
throw new error_1.FirebaseError(`Error during npm run build in ${shortDirPath}: ${errMsg}`);
|
|
360
363
|
}
|
|
361
364
|
const codebaseDir = (0, common_1.getCodebaseDir)(options);
|
|
@@ -372,7 +375,7 @@ async function writeSDK(extensionRef, localPath, spec, options) {
|
|
|
372
375
|
(0, child_process_1.execFileSync)("npm", ["--prefix", codebaseDir, "install", "--save", dirPath]);
|
|
373
376
|
}
|
|
374
377
|
catch (err) {
|
|
375
|
-
const errMsg = (0,
|
|
378
|
+
const errMsg = (0, error_1.getErrMsg)(err, "unknown error");
|
|
376
379
|
throw new error_1.FirebaseError(`Error during npm install in ${codebaseDir}: ${errMsg}`);
|
|
377
380
|
}
|
|
378
381
|
}
|
package/lib/extensions/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isExtensionSpec = exports.isResource = exports.isParam = exports.isObject = exports.ParamType = exports.FUNCTIONS_V2_RESOURCE_TYPE = exports.FUNCTIONS_RESOURCE_TYPE = exports.Visibility = exports.RegistryLaunchStage = void 0;
|
|
3
|
+
exports.isExtensionSpec = exports.isResource = exports.isParam = exports.isObject = exports.ParamType = exports.FUNCTIONS_V2_RESOURCE_TYPE = exports.FUNCTIONS_RESOURCE_TYPE = exports.isExtensionInstance = exports.Visibility = exports.RegistryLaunchStage = void 0;
|
|
4
4
|
var RegistryLaunchStage;
|
|
5
5
|
(function (RegistryLaunchStage) {
|
|
6
6
|
RegistryLaunchStage["EXPERIMENTAL"] = "EXPERIMENTAL";
|
|
@@ -14,6 +14,21 @@ var Visibility;
|
|
|
14
14
|
Visibility["UNLISTED"] = "unlisted";
|
|
15
15
|
Visibility["PUBLIC"] = "public";
|
|
16
16
|
})(Visibility = exports.Visibility || (exports.Visibility = {}));
|
|
17
|
+
const extensionInstanceState = [
|
|
18
|
+
"STATE_UNSPECIFIED",
|
|
19
|
+
"DEPLOYING",
|
|
20
|
+
"UNINSTALLING",
|
|
21
|
+
"ACTIVE",
|
|
22
|
+
"ERRORED",
|
|
23
|
+
"PAUSED",
|
|
24
|
+
];
|
|
25
|
+
const isExtensionInstance = (value) => {
|
|
26
|
+
if (!isObject(value) || typeof value.name !== "string") {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
31
|
+
exports.isExtensionInstance = isExtensionInstance;
|
|
17
32
|
const lifecycleStages = ["STAGE_UNSPECIFIED", "ON_INSTALL", "ON_UPDATE", "ON_CONFIGURE"];
|
|
18
33
|
exports.FUNCTIONS_RESOURCE_TYPE = "firebaseextensions.v1beta.function";
|
|
19
34
|
exports.FUNCTIONS_V2_RESOURCE_TYPE = "firebaseextensions.v1beta.v2function";
|
|
@@ -57,19 +57,19 @@ var ValueType;
|
|
|
57
57
|
ValueType["DOUBLE"] = "DOUBLE";
|
|
58
58
|
ValueType["STRING"] = "STRING";
|
|
59
59
|
})(ValueType = exports.ValueType || (exports.ValueType = {}));
|
|
60
|
-
async function queryTimeSeries(query,
|
|
60
|
+
async function queryTimeSeries(query, project) {
|
|
61
61
|
const client = new apiv2_1.Client({
|
|
62
62
|
urlPrefix: (0, api_1.cloudMonitoringOrigin)(),
|
|
63
63
|
apiVersion: exports.CLOUD_MONITORING_VERSION,
|
|
64
64
|
});
|
|
65
65
|
try {
|
|
66
|
-
const res = await client.get(`/projects/${
|
|
66
|
+
const res = await client.get(`/projects/${project}/timeSeries/`, {
|
|
67
67
|
queryParams: query,
|
|
68
68
|
});
|
|
69
69
|
return res.body.timeSeries;
|
|
70
70
|
}
|
|
71
71
|
catch (err) {
|
|
72
|
-
throw new error_1.FirebaseError(`Failed to get
|
|
72
|
+
throw new error_1.FirebaseError(`Failed to get Cloud Monitoring metric: ${err}`, {
|
|
73
73
|
status: err.status,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
@@ -34,27 +34,34 @@ async function createInstance(projectId, location, instanceId, enableGoogleMlInt
|
|
|
34
34
|
if (enableGoogleMlIntegration) {
|
|
35
35
|
databaseFlags.push({ name: "cloudsql.enable_google_ml_integration", value: "on" });
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
37
|
+
let op;
|
|
38
|
+
try {
|
|
39
|
+
op = await client.post(`projects/${projectId}/instances`, {
|
|
40
|
+
name: instanceId,
|
|
41
|
+
region: location,
|
|
42
|
+
databaseVersion: "POSTGRES_15",
|
|
43
|
+
settings: {
|
|
44
|
+
tier: "db-f1-micro",
|
|
45
|
+
edition: "ENTERPRISE",
|
|
46
|
+
ipConfiguration: {
|
|
47
|
+
authorizedNetworks: [],
|
|
48
|
+
},
|
|
49
|
+
enableGoogleMlIntegration,
|
|
50
|
+
databaseFlags,
|
|
51
|
+
storageAutoResize: false,
|
|
52
|
+
userLabels: { "firebase-data-connect": "ft" },
|
|
53
|
+
insightsConfig: {
|
|
54
|
+
queryInsightsEnabled: true,
|
|
55
|
+
queryPlansPerMinute: 5,
|
|
56
|
+
queryStringLength: 1024,
|
|
57
|
+
},
|
|
55
58
|
},
|
|
56
|
-
}
|
|
57
|
-
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
handleAllowlistError(err, location);
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
58
65
|
if (!waitForCreation) {
|
|
59
66
|
return;
|
|
60
67
|
}
|
|
@@ -94,6 +101,11 @@ async function updateInstanceForDataConnect(instance, enableGoogleMlIntegration)
|
|
|
94
101
|
return pollRes;
|
|
95
102
|
}
|
|
96
103
|
exports.updateInstanceForDataConnect = updateInstanceForDataConnect;
|
|
104
|
+
function handleAllowlistError(err, region) {
|
|
105
|
+
if (err.message.includes("Not allowed to set system label: firebase-data-connect")) {
|
|
106
|
+
throw new error_1.FirebaseError(`Cloud SQL free trial instances are not yet available in ${region}. Please check https://firebase.google.com/docs/data-connect/ for a full list of available regions.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
97
109
|
function setDatabaseFlag(flag, flags = []) {
|
|
98
110
|
const temp = flags.filter((f) => f.name !== flag.name);
|
|
99
111
|
temp.push(flag);
|
package/lib/gcp/devConnect.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateP4SA = exports.serviceAgentEmail = exports.sortConnectionsByCreateTime = exports.getGitRepositoryLink = exports.createGitRepositoryLink = exports.fetchGitHubInstallations = exports.listAllBranches = exports.listAllLinkableGitRepositories = exports.listAllConnections = exports.getConnection = exports.deleteConnection = exports.createConnection = exports.client = void 0;
|
|
3
|
+
exports.getRepoDetailsFromBackend = exports.extractGitRepositoryLinkComponents = exports.generateP4SA = exports.serviceAgentEmail = exports.sortConnectionsByCreateTime = exports.fetchGitRepositoryLinkReadToken = exports.getGitRepositoryLink = exports.createGitRepositoryLink = exports.fetchGitHubInstallations = exports.listAllBranches = exports.listAllLinkableGitRepositories = exports.listAllConnections = exports.getConnection = exports.deleteConnection = exports.createConnection = exports.client = void 0;
|
|
4
4
|
const apiv2_1 = require("../apiv2");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
6
|
const serviceusage_1 = require("./serviceusage");
|
|
7
|
+
const error_1 = require("../error");
|
|
8
|
+
const githubConnections_1 = require("../apphosting/githubConnections");
|
|
7
9
|
const PAGE_SIZE_MAX = 1000;
|
|
8
10
|
const LOCATION_OVERRIDE = process.env.FIREBASE_DEVELOPERCONNECT_LOCATION_OVERRIDE;
|
|
9
11
|
exports.client = new apiv2_1.Client({
|
|
@@ -112,6 +114,12 @@ async function getGitRepositoryLink(projectId, location, connectionId, gitReposi
|
|
|
112
114
|
return res.body;
|
|
113
115
|
}
|
|
114
116
|
exports.getGitRepositoryLink = getGitRepositoryLink;
|
|
117
|
+
async function fetchGitRepositoryLinkReadToken(projectId, location, connectionId, gitRepositoryLinkId) {
|
|
118
|
+
const name = `projects/${projectId}/locations/${LOCATION_OVERRIDE !== null && LOCATION_OVERRIDE !== void 0 ? LOCATION_OVERRIDE : location}/connections/${connectionId}/gitRepositoryLinks/${gitRepositoryLinkId}:fetchReadToken`;
|
|
119
|
+
const res = await exports.client.post(name);
|
|
120
|
+
return res.body;
|
|
121
|
+
}
|
|
122
|
+
exports.fetchGitRepositoryLinkReadToken = fetchGitRepositoryLinkReadToken;
|
|
115
123
|
function sortConnectionsByCreateTime(connections) {
|
|
116
124
|
return connections.sort((a, b) => {
|
|
117
125
|
return Date.parse(a.createTime) - Date.parse(b.createTime);
|
|
@@ -127,3 +135,32 @@ async function generateP4SA(projectNumber) {
|
|
|
127
135
|
await (0, serviceusage_1.generateServiceIdentityAndPoll)(projectNumber, new URL(devConnectOrigin).hostname, "apphosting");
|
|
128
136
|
}
|
|
129
137
|
exports.generateP4SA = generateP4SA;
|
|
138
|
+
function extractGitRepositoryLinkComponents(path) {
|
|
139
|
+
const connectionMatch = /connections\/([^\/]+)/.exec(path);
|
|
140
|
+
const repositoryMatch = /gitRepositoryLinks\/([^\/]+)/.exec(path);
|
|
141
|
+
const connection = connectionMatch ? connectionMatch[1] : null;
|
|
142
|
+
const gitRepoLink = repositoryMatch ? repositoryMatch[1] : null;
|
|
143
|
+
return { connection, gitRepoLink };
|
|
144
|
+
}
|
|
145
|
+
exports.extractGitRepositoryLinkComponents = extractGitRepositoryLinkComponents;
|
|
146
|
+
async function getRepoDetailsFromBackend(projectId, location, gitRepoLinkPath) {
|
|
147
|
+
const { connection, gitRepoLink } = extractGitRepositoryLinkComponents(gitRepoLinkPath);
|
|
148
|
+
if (!connection || !gitRepoLink) {
|
|
149
|
+
throw new error_1.FirebaseError(`Failed to extract connection or repository resource names from backend repository name.`);
|
|
150
|
+
}
|
|
151
|
+
const repoLink = await getGitRepositoryLink(projectId, location, connection, gitRepoLink);
|
|
152
|
+
const repoSlug = (0, githubConnections_1.extractRepoSlugFromUri)(repoLink.cloneUri);
|
|
153
|
+
const owner = repoSlug === null || repoSlug === void 0 ? void 0 : repoSlug.split("/")[0];
|
|
154
|
+
const repo = repoSlug === null || repoSlug === void 0 ? void 0 : repoSlug.split("/")[1];
|
|
155
|
+
if (!owner || !repo) {
|
|
156
|
+
throw new error_1.FirebaseError("Failed to parse owner and repo from git repository link");
|
|
157
|
+
}
|
|
158
|
+
const readToken = await fetchGitRepositoryLinkReadToken(projectId, location, connection, gitRepoLink);
|
|
159
|
+
return {
|
|
160
|
+
repoLink,
|
|
161
|
+
owner,
|
|
162
|
+
repo,
|
|
163
|
+
readToken,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
exports.getRepoDetailsFromBackend = getRepoDetailsFromBackend;
|