firebase-tools 13.22.0 → 13.23.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/apiv2.js +2 -2
- package/lib/apphosting/githubConnections.js +36 -11
- package/lib/apphosting/index.js +19 -1
- package/lib/auth.js +13 -1
- package/lib/commands/apphosting-repos-create.js +23 -0
- package/lib/commands/dataconnect-sql-shell.js +111 -0
- package/lib/commands/index.js +3 -0
- package/lib/crashlytics/buildToolsJarHelper.js +2 -2
- package/lib/dataconnect/schemaMigration.js +2 -1
- package/lib/deploy/functions/runtimes/discovery/index.js +6 -2
- package/lib/deploy/functions/services/auth.js +40 -15
- package/lib/deploy/functions/services/index.js +2 -0
- package/lib/emulator/apphosting/index.js +3 -2
- package/lib/emulator/apphosting/serve.js +14 -5
- package/lib/emulator/controller.js +15 -4
- package/lib/emulator/downloadableEmulators.js +9 -9
- package/lib/emulator/functionsRuntimeWorker.js +2 -1
- package/lib/emulator/hubExport.js +10 -3
- package/lib/emulator/storage/persistence.js +2 -2
- package/lib/extensions/extensionsHelper.js +12 -3
- package/lib/firestore/delete.js +11 -0
- package/lib/frameworks/constants.js +1 -1
- package/lib/frameworks/flutter/index.js +6 -6
- package/lib/frameworks/flutter/utils.js +34 -1
- package/lib/functions/constants.js +4 -0
- package/lib/functions/events/v1.js +9 -2
- package/lib/gcp/cloudsql/interactive.js +49 -0
- package/lib/gcp/firestore.js +5 -1
- package/lib/init/features/hosting/index.js +2 -2
- package/lib/init/spawn.js +21 -1
- package/lib/requireAuth.js +11 -1
- package/lib/responseToError.js +5 -2
- package/package.json +1 -2
- package/schema/firebase-config.json +3 -0
- package/templates/extensions/javascript/package.lint.json +2 -2
- package/templates/extensions/javascript/package.nolint.json +2 -2
- package/templates/extensions/typescript/package.lint.json +2 -2
- package/templates/extensions/typescript/package.nolint.json +2 -2
- package/templates/init/functions/javascript/package.lint.json +2 -2
- package/templates/init/functions/javascript/package.nolint.json +2 -2
- package/templates/init/functions/typescript/package.lint.json +2 -2
- package/templates/init/functions/typescript/package.nolint.json +2 -2
package/lib/apiv2.js
CHANGED
|
@@ -303,13 +303,13 @@ class Client {
|
|
|
303
303
|
setAccessToken(await getAccessToken());
|
|
304
304
|
}
|
|
305
305
|
if ((_a = options.retryCodes) === null || _a === void 0 ? void 0 : _a.includes(res.status)) {
|
|
306
|
-
const err = (0, responseToError_1.responseToError)({ statusCode: res.status }, body) || undefined;
|
|
306
|
+
const err = (0, responseToError_1.responseToError)({ statusCode: res.status }, body, fetchURL) || undefined;
|
|
307
307
|
if (operation.retry(err)) {
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
311
|
if (!options.resolveOnHTTPError) {
|
|
312
|
-
return reject((0, responseToError_1.responseToError)({ statusCode: res.status }, body));
|
|
312
|
+
return reject((0, responseToError_1.responseToError)({ statusCode: res.status }, body, fetchURL));
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
315
|
resolve({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getGitHubCommit = exports.getGitHubBranch = exports.fetchRepositoryCloneUris = exports.listAppHostingConnections = exports.getOrCreateRepository = exports.getOrCreateConnection = exports.createConnection = exports.ensureSecretManagerAdminGrant = exports.promptGitHubBranch = exports.getOrCreateOauthConnection = exports.listValidInstallations = exports.promptGitHubInstallation = exports.getConnectionForInstallation = exports.linkGitHubRepository = exports.generateRepositoryId = exports.extractRepoSlugFromUri = exports.parseConnectionName = void 0;
|
|
3
|
+
exports.getGitHubCommit = exports.getGitHubBranch = exports.fetchRepositoryCloneUris = exports.listAppHostingConnections = exports.getOrCreateRepository = exports.getOrCreateConnection = exports.createConnection = exports.ensureSecretManagerAdminGrant = exports.promptGitHubBranch = exports.getOrCreateOauthConnection = exports.listValidInstallations = exports.promptGitHubInstallation = exports.getConnectionForInstallation = exports.linkGitHubRepository = exports.getOrCreateGithubConnectionWithSentinel = exports.generateRepositoryId = exports.extractRepoSlugFromUri = exports.parseConnectionName = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const devConnect = require("../gcp/devConnect");
|
|
6
6
|
const rm = require("../gcp/resourceManager");
|
|
@@ -55,9 +55,20 @@ function generateConnectionId() {
|
|
|
55
55
|
}
|
|
56
56
|
const ADD_ACCOUNT_CHOICE = "@ADD_ACCOUNT";
|
|
57
57
|
const MANAGE_INSTALLATION_CHOICE = "@MANAGE_INSTALLATION";
|
|
58
|
-
async function
|
|
59
|
-
var _a, _b;
|
|
58
|
+
async function getOrCreateGithubConnectionWithSentinel(projectId, location, createConnectionId) {
|
|
60
59
|
utils.logBullet(clc.bold(`${clc.yellow("===")} Import a GitHub repository`));
|
|
60
|
+
if (createConnectionId) {
|
|
61
|
+
try {
|
|
62
|
+
const connection = await devConnect.getConnection(projectId, location, createConnectionId);
|
|
63
|
+
utils.logBullet(`Reusing existing connection ${createConnectionId}`);
|
|
64
|
+
return connection;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err.status !== 404) {
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
61
72
|
const oauthConn = await getOrCreateOauthConnection(projectId, location);
|
|
62
73
|
let installationId = await promptGitHubInstallation(projectId, location, oauthConn);
|
|
63
74
|
while (installationId === ADD_ACCOUNT_CHOICE) {
|
|
@@ -71,21 +82,35 @@ async function linkGitHubRepository(projectId, location) {
|
|
|
71
82
|
});
|
|
72
83
|
installationId = await promptGitHubInstallation(projectId, location, oauthConn);
|
|
73
84
|
}
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
|
|
85
|
+
const connectionMatchingInstallation = await getConnectionForInstallation(projectId, location, installationId);
|
|
86
|
+
if (connectionMatchingInstallation) {
|
|
87
|
+
const { id: matchingConnectionId } = parseConnectionName(connectionMatchingInstallation.name);
|
|
88
|
+
if (!createConnectionId) {
|
|
89
|
+
utils.logBullet(`Reusing matching connection ${matchingConnectionId}`);
|
|
90
|
+
return connectionMatchingInstallation;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!createConnectionId) {
|
|
94
|
+
createConnectionId = generateConnectionId();
|
|
77
95
|
}
|
|
96
|
+
const connection = await createFullyInstalledConnection(projectId, location, createConnectionId, oauthConn, installationId);
|
|
97
|
+
return connection;
|
|
98
|
+
}
|
|
99
|
+
exports.getOrCreateGithubConnectionWithSentinel = getOrCreateGithubConnectionWithSentinel;
|
|
100
|
+
async function linkGitHubRepository(projectId, location, createConnectionId) {
|
|
101
|
+
var _a, _b;
|
|
102
|
+
const connection = await getOrCreateGithubConnectionWithSentinel(projectId, location, createConnectionId);
|
|
78
103
|
let repoCloneUri;
|
|
79
104
|
do {
|
|
80
105
|
if (repoCloneUri === MANAGE_INSTALLATION_CHOICE) {
|
|
81
|
-
await manageInstallation(
|
|
106
|
+
await manageInstallation(connection);
|
|
82
107
|
}
|
|
83
|
-
repoCloneUri = await promptCloneUri(projectId,
|
|
108
|
+
repoCloneUri = await promptCloneUri(projectId, connection);
|
|
84
109
|
} while (repoCloneUri === MANAGE_INSTALLATION_CHOICE);
|
|
85
|
-
const { id: connectionId } = parseConnectionName(
|
|
110
|
+
const { id: connectionId } = parseConnectionName(connection.name);
|
|
86
111
|
await getOrCreateConnection(projectId, location, connectionId, {
|
|
87
|
-
authorizerCredential: (_a =
|
|
88
|
-
appInstallationId: (_b =
|
|
112
|
+
authorizerCredential: (_a = connection.githubConfig) === null || _a === void 0 ? void 0 : _a.authorizerCredential,
|
|
113
|
+
appInstallationId: (_b = connection.githubConfig) === null || _b === void 0 ? void 0 : _b.appInstallationId,
|
|
89
114
|
});
|
|
90
115
|
const repo = await getOrCreateRepository(projectId, location, connectionId, repoCloneUri);
|
|
91
116
|
return repo;
|
package/lib/apphosting/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBackendForAmbiguousLocation = exports.promptLocation = exports.deleteBackendAndPoll = exports.setDefaultTrafficPolicy = exports.createBackend = exports.ensureAppHostingComputeServiceAccount = exports.doSetup = void 0;
|
|
3
|
+
exports.getBackendForAmbiguousLocation = exports.promptLocation = exports.deleteBackendAndPoll = exports.setDefaultTrafficPolicy = exports.createBackend = exports.ensureAppHostingComputeServiceAccount = exports.createGitRepoLink = exports.doSetup = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const poller = require("../operation-poller");
|
|
6
6
|
const apphosting = require("../gcp/apphosting");
|
|
@@ -128,6 +128,24 @@ async function doSetup(projectId, webAppName, location, serviceAccount) {
|
|
|
128
128
|
(0, utils_1.logSuccess)(`Your backend is now deployed at:\n\thttps://${backend.uri}`);
|
|
129
129
|
}
|
|
130
130
|
exports.doSetup = doSetup;
|
|
131
|
+
async function createGitRepoLink(projectId, location, connectionId) {
|
|
132
|
+
await Promise.all([
|
|
133
|
+
(0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.developerConnectOrigin)(), "apphosting", true),
|
|
134
|
+
(0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.secretManagerOrigin)(), "apphosting", true),
|
|
135
|
+
(0, ensureApiEnabled_1.ensure)(projectId, (0, api_1.iamOrigin)(), "apphosting", true),
|
|
136
|
+
]);
|
|
137
|
+
const allowedLocations = (await apphosting.listLocations(projectId)).map((loc) => loc.locationId);
|
|
138
|
+
if (location) {
|
|
139
|
+
if (!allowedLocations.includes(location)) {
|
|
140
|
+
throw new error_1.FirebaseError(`Invalid location ${location}. Valid choices are ${allowedLocations.join(", ")}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
location =
|
|
144
|
+
location ||
|
|
145
|
+
(await promptLocation(projectId, "Select a location for your GitRepoLink's connection:\n"));
|
|
146
|
+
await githubConnections.linkGitHubRepository(projectId, location, connectionId);
|
|
147
|
+
}
|
|
148
|
+
exports.createGitRepoLink = createGitRepoLink;
|
|
131
149
|
async function ensureAppHostingComputeServiceAccount(projectId, serviceAccount) {
|
|
132
150
|
const sa = serviceAccount || defaultComputeServiceAccountEmail(projectId);
|
|
133
151
|
const name = `projects/${projectId}/serviceAccounts/${sa}`;
|
package/lib/auth.js
CHANGED
|
@@ -21,6 +21,7 @@ const crypto_1 = require("crypto");
|
|
|
21
21
|
const track_1 = require("./track");
|
|
22
22
|
const api_1 = require("./api");
|
|
23
23
|
const templates_1 = require("./templates");
|
|
24
|
+
const requireAuth_1 = require("./requireAuth");
|
|
24
25
|
portfinder.setBasePort(9005);
|
|
25
26
|
function getGlobalDefaultAccount() {
|
|
26
27
|
const user = configstore_1.configstore.get("user");
|
|
@@ -530,7 +531,18 @@ async function getAccessToken(refreshToken, authScopes) {
|
|
|
530
531
|
if (haveValidTokens(refreshToken, authScopes) && lastAccessToken) {
|
|
531
532
|
return lastAccessToken;
|
|
532
533
|
}
|
|
533
|
-
|
|
534
|
+
if (refreshToken) {
|
|
535
|
+
return refreshTokens(refreshToken, authScopes);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
try {
|
|
539
|
+
return (0, requireAuth_1.refreshAuth)();
|
|
540
|
+
}
|
|
541
|
+
catch (err) {
|
|
542
|
+
logger_1.logger.debug(`Unable to refresh token: ${err}`);
|
|
543
|
+
}
|
|
544
|
+
throw new error_1.FirebaseError("Unable to getAccessToken");
|
|
545
|
+
}
|
|
534
546
|
}
|
|
535
547
|
exports.getAccessToken = getAccessToken;
|
|
536
548
|
async function logout(refreshToken) {
|
|
@@ -0,0 +1,23 @@
|
|
|
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 requireInteractive_1 = require("../requireInteractive");
|
|
7
|
+
const apphosting_1 = require("../apphosting");
|
|
8
|
+
const apphosting_2 = require("../gcp/apphosting");
|
|
9
|
+
const firedata_1 = require("../gcp/firedata");
|
|
10
|
+
const requireTosAcceptance_1 = require("../requireTosAcceptance");
|
|
11
|
+
exports.command = new command_1.Command("apphosting:repos:create")
|
|
12
|
+
.description("create a Firebase App Hosting Developer Connect Git Repository Link")
|
|
13
|
+
.option("-l, --location <location>", "specify the location of the backend", "")
|
|
14
|
+
.option("-g, --gitconnection <connection>", "id of the connection", "")
|
|
15
|
+
.before(apphosting_2.ensureApiEnabled)
|
|
16
|
+
.before(requireInteractive_1.default)
|
|
17
|
+
.before((0, requireTosAcceptance_1.requireTosAcceptance)(firedata_1.APPHOSTING_TOS_ID))
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
20
|
+
const location = options.location;
|
|
21
|
+
const connection = options.gitconnection;
|
|
22
|
+
await (0, apphosting_1.createGitRepoLink)(projectId, location, connection);
|
|
23
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const pg = require("pg");
|
|
5
|
+
const clc = require("colorette");
|
|
6
|
+
const cloud_sql_connector_1 = require("@google-cloud/cloud-sql-connector");
|
|
7
|
+
const command_1 = require("../command");
|
|
8
|
+
const projectUtils_1 = require("../projectUtils");
|
|
9
|
+
const ensureApis_1 = require("../dataconnect/ensureApis");
|
|
10
|
+
const requirePermissions_1 = require("../requirePermissions");
|
|
11
|
+
const fileUtils_1 = require("../dataconnect/fileUtils");
|
|
12
|
+
const schemaMigration_1 = require("../dataconnect/schemaMigration");
|
|
13
|
+
const requireAuth_1 = require("../requireAuth");
|
|
14
|
+
const connect_1 = require("../gcp/cloudsql/connect");
|
|
15
|
+
const cloudSqlAdminClient = require("../gcp/cloudsql/cloudsqladmin");
|
|
16
|
+
const prompt_1 = require("../prompt");
|
|
17
|
+
const logger_1 = require("../logger");
|
|
18
|
+
const error_1 = require("../error");
|
|
19
|
+
const fbToolsAuthClient_1 = require("../gcp/cloudsql/fbToolsAuthClient");
|
|
20
|
+
const interactive_1 = require("../gcp/cloudsql/interactive");
|
|
21
|
+
const sqlKeywords = [
|
|
22
|
+
"SELECT",
|
|
23
|
+
"FROM",
|
|
24
|
+
"WHERE",
|
|
25
|
+
"INSERT",
|
|
26
|
+
"UPDATE",
|
|
27
|
+
"DELETE",
|
|
28
|
+
"JOIN",
|
|
29
|
+
"GROUP",
|
|
30
|
+
"ORDER",
|
|
31
|
+
"LIMIT",
|
|
32
|
+
"GRANT",
|
|
33
|
+
"CREATE",
|
|
34
|
+
"DROP",
|
|
35
|
+
];
|
|
36
|
+
async function promptForQuery() {
|
|
37
|
+
let query = "";
|
|
38
|
+
let line = "";
|
|
39
|
+
do {
|
|
40
|
+
const question = {
|
|
41
|
+
type: "input",
|
|
42
|
+
name: "line",
|
|
43
|
+
message: query ? "> " : "Enter your SQL query (or '.exit'):",
|
|
44
|
+
transformer: (input) => {
|
|
45
|
+
return input
|
|
46
|
+
.split(" ")
|
|
47
|
+
.map((word) => (sqlKeywords.includes(word.toUpperCase()) ? clc.cyan(word) : word))
|
|
48
|
+
.join(" ");
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
({ line } = await (0, prompt_1.prompt)({ nonInteractive: false }, [question]));
|
|
52
|
+
line = line.trimEnd();
|
|
53
|
+
if (line.toLowerCase() === ".exit") {
|
|
54
|
+
return ".exit";
|
|
55
|
+
}
|
|
56
|
+
query += (query ? "\n" : "") + line;
|
|
57
|
+
} while (line !== "" && !query.endsWith(";"));
|
|
58
|
+
return query;
|
|
59
|
+
}
|
|
60
|
+
async function mainShellLoop(conn) {
|
|
61
|
+
while (true) {
|
|
62
|
+
const query = await promptForQuery();
|
|
63
|
+
if (query.toLowerCase() === ".exit") {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if (query === "") {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (await (0, interactive_1.confirmDangerousQuery)(query)) {
|
|
70
|
+
await (0, interactive_1.interactiveExecuteQuery)(query, conn);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logger_1.logger.info(clc.yellow("Query cancelled."));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.command = new command_1.Command("dataconnect:sql:shell [serviceId]")
|
|
78
|
+
.description("Starts a shell connected directly to your dataconnect cloudsql instance.")
|
|
79
|
+
.before(requirePermissions_1.requirePermissions, ["firebasedataconnect.services.list", "cloudsql.instances.connect"])
|
|
80
|
+
.before(requireAuth_1.requireAuth)
|
|
81
|
+
.action(async (serviceId, options) => {
|
|
82
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
83
|
+
await (0, ensureApis_1.ensureApis)(projectId);
|
|
84
|
+
const serviceInfo = await (0, fileUtils_1.pickService)(projectId, options.config, serviceId);
|
|
85
|
+
const { instanceId, databaseId } = (0, schemaMigration_1.getIdentifiers)(serviceInfo.schema);
|
|
86
|
+
const { user: username } = await (0, connect_1.getIAMUser)(options);
|
|
87
|
+
const instance = await cloudSqlAdminClient.getInstance(projectId, instanceId);
|
|
88
|
+
const connectionName = instance.connectionName;
|
|
89
|
+
if (!connectionName) {
|
|
90
|
+
throw new error_1.FirebaseError(`Could not get instance connection string for ${options.instanceId}:${options.databaseId}`);
|
|
91
|
+
}
|
|
92
|
+
const connector = new cloud_sql_connector_1.Connector({
|
|
93
|
+
auth: new fbToolsAuthClient_1.FBToolsAuthClient(),
|
|
94
|
+
});
|
|
95
|
+
const clientOpts = await connector.getOptions({
|
|
96
|
+
instanceConnectionName: connectionName,
|
|
97
|
+
ipType: cloud_sql_connector_1.IpAddressTypes.PUBLIC,
|
|
98
|
+
authType: cloud_sql_connector_1.AuthTypes.IAM,
|
|
99
|
+
});
|
|
100
|
+
const pool = new pg.Pool(Object.assign(Object.assign({}, clientOpts), { user: username, database: databaseId }));
|
|
101
|
+
const conn = await pool.connect();
|
|
102
|
+
logger_1.logger.info(`Logged in as ${username}`);
|
|
103
|
+
logger_1.logger.info(clc.cyan("Welcome to Data Connect Cloud SQL Shell"));
|
|
104
|
+
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."));
|
|
105
|
+
await mainShellLoop(conn);
|
|
106
|
+
logger_1.logger.info(clc.yellow("Exiting shell..."));
|
|
107
|
+
conn.release();
|
|
108
|
+
await pool.end();
|
|
109
|
+
connector.close();
|
|
110
|
+
return { projectId, serviceId };
|
|
111
|
+
});
|
package/lib/commands/index.js
CHANGED
|
@@ -173,6 +173,8 @@ function load(client) {
|
|
|
173
173
|
client.apphosting.builds = {};
|
|
174
174
|
client.apphosting.builds.get = loadCommand("apphosting-builds-get");
|
|
175
175
|
client.apphosting.builds.create = loadCommand("apphosting-builds-create");
|
|
176
|
+
client.apphosting.repos = {};
|
|
177
|
+
client.apphosting.repos.create = loadCommand("apphosting-repos-create");
|
|
176
178
|
client.apphosting.rollouts = {};
|
|
177
179
|
client.apphosting.rollouts.create = loadCommand("apphosting-rollouts-create");
|
|
178
180
|
client.apphosting.rollouts.list = loadCommand("apphosting-rollouts-list");
|
|
@@ -210,6 +212,7 @@ function load(client) {
|
|
|
210
212
|
client.dataconnect.sql.diff = loadCommand("dataconnect-sql-diff");
|
|
211
213
|
client.dataconnect.sql.migrate = loadCommand("dataconnect-sql-migrate");
|
|
212
214
|
client.dataconnect.sql.grant = loadCommand("dataconnect-sql-grant");
|
|
215
|
+
client.dataconnect.sql.shell = loadCommand("dataconnect-sql-shell");
|
|
213
216
|
client.dataconnect.sdk = {};
|
|
214
217
|
client.dataconnect.sdk.generate = loadCommand("dataconnect-sdk-generate");
|
|
215
218
|
client.target = loadCommand("target");
|
|
@@ -8,7 +8,7 @@ const spawn = require("cross-spawn");
|
|
|
8
8
|
const downloadUtils = require("../downloadUtils");
|
|
9
9
|
const error_1 = require("../error");
|
|
10
10
|
const logger_1 = require("../logger");
|
|
11
|
-
const
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
12
|
const utils = require("../utils");
|
|
13
13
|
const JAR_CACHE_DIR = process.env.FIREBASE_CRASHLYTICS_BUILDTOOLS_PATH ||
|
|
14
14
|
path.join(os.homedir(), ".cache", "firebase", "crashlytics", "buildtools");
|
|
@@ -26,7 +26,7 @@ async function fetchBuildtoolsJar() {
|
|
|
26
26
|
}
|
|
27
27
|
if (fs.existsSync(JAR_CACHE_DIR)) {
|
|
28
28
|
logger_1.logger.debug(`Deleting Jar cache at ${JAR_CACHE_DIR} because the CLI was run with a newer Jar version`);
|
|
29
|
-
|
|
29
|
+
(0, node_fs_1.rmSync)(JAR_CACHE_DIR, { recursive: true });
|
|
30
30
|
}
|
|
31
31
|
utils.logBullet("Downloading crashlytics-buildtools.jar to " + jarPath);
|
|
32
32
|
utils.logBullet("For open source licenses used by this command, look in the META-INF directory in the buildtools.jar file");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.grantRoleToUserInSchema = exports.migrateSchema = exports.diffSchema = void 0;
|
|
3
|
+
exports.getIdentifiers = exports.grantRoleToUserInSchema = exports.migrateSchema = exports.diffSchema = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const sql_formatter_1 = require("sql-formatter");
|
|
6
6
|
const types_1 = require("./types");
|
|
@@ -212,6 +212,7 @@ function getIdentifiers(schema) {
|
|
|
212
212
|
serviceName,
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
|
+
exports.getIdentifiers = getIdentifiers;
|
|
215
216
|
function suggestedCommand(serviceName, invalidConnectorNames) {
|
|
216
217
|
const serviceId = serviceName.split("/")[5];
|
|
217
218
|
const connectorIds = invalidConnectorNames.map((i) => i.split("/")[7]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.detectFromPort = exports.detectFromYaml = exports.yamlToBuild = exports.readFileAsync = void 0;
|
|
3
|
+
exports.detectFromPort = exports.detectFromYaml = exports.yamlToBuild = exports.getFunctionDiscoveryTimeout = exports.readFileAsync = void 0;
|
|
4
4
|
const node_fetch_1 = require("node-fetch");
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
@@ -12,6 +12,10 @@ const v1alpha1 = require("./v1alpha1");
|
|
|
12
12
|
const error_1 = require("../../../../error");
|
|
13
13
|
exports.readFileAsync = (0, util_1.promisify)(fs.readFile);
|
|
14
14
|
const TIMEOUT_OVERRIDE_ENV_VAR = "FUNCTIONS_DISCOVERY_TIMEOUT";
|
|
15
|
+
function getFunctionDiscoveryTimeout() {
|
|
16
|
+
return +(process.env[TIMEOUT_OVERRIDE_ENV_VAR] || 0) * 1000;
|
|
17
|
+
}
|
|
18
|
+
exports.getFunctionDiscoveryTimeout = getFunctionDiscoveryTimeout;
|
|
15
19
|
function yamlToBuild(yaml, project, region, runtime) {
|
|
16
20
|
try {
|
|
17
21
|
if (!yaml.specVersion) {
|
|
@@ -51,7 +55,7 @@ async function detectFromPort(port, project, runtime, timeout = 10000) {
|
|
|
51
55
|
const timedOut = new Promise((resolve, reject) => {
|
|
52
56
|
setTimeout(() => {
|
|
53
57
|
reject(new error_1.FirebaseError("User code failed to load. Cannot determine backend specification"));
|
|
54
|
-
},
|
|
58
|
+
}, getFunctionDiscoveryTimeout() || timeout);
|
|
55
59
|
});
|
|
56
60
|
while (true) {
|
|
57
61
|
try {
|
|
@@ -27,18 +27,22 @@ class AuthBlockingService {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
configChanged(newConfig, config) {
|
|
30
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
30
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
31
31
|
if (((_b = (_a = newConfig.triggers) === null || _a === void 0 ? void 0 : _a.beforeCreate) === null || _b === void 0 ? void 0 : _b.functionUri) !==
|
|
32
32
|
((_d = (_c = config.triggers) === null || _c === void 0 ? void 0 : _c.beforeCreate) === null || _d === void 0 ? void 0 : _d.functionUri) ||
|
|
33
|
-
((_f = (_e = newConfig.triggers) === null || _e === void 0 ? void 0 : _e.beforeSignIn) === null || _f === void 0 ? void 0 : _f.functionUri) !==
|
|
33
|
+
((_f = (_e = newConfig.triggers) === null || _e === void 0 ? void 0 : _e.beforeSignIn) === null || _f === void 0 ? void 0 : _f.functionUri) !==
|
|
34
|
+
((_h = (_g = config.triggers) === null || _g === void 0 ? void 0 : _g.beforeSignIn) === null || _h === void 0 ? void 0 : _h.functionUri) ||
|
|
35
|
+
((_k = (_j = newConfig.triggers) === null || _j === void 0 ? void 0 : _j.beforeSendEmail) === null || _k === void 0 ? void 0 : _k.functionUri) !==
|
|
36
|
+
((_m = (_l = config.triggers) === null || _l === void 0 ? void 0 : _l.beforeSendEmail) === null || _m === void 0 ? void 0 : _m.functionUri) ||
|
|
37
|
+
((_p = (_o = newConfig.triggers) === null || _o === void 0 ? void 0 : _o.beforeSendSms) === null || _p === void 0 ? void 0 : _p.functionUri) !== ((_r = (_q = config.triggers) === null || _q === void 0 ? void 0 : _q.beforeSendSms) === null || _r === void 0 ? void 0 : _r.functionUri)) {
|
|
34
38
|
return true;
|
|
35
39
|
}
|
|
36
|
-
if (!!((
|
|
37
|
-
!!((
|
|
38
|
-
!!((
|
|
39
|
-
!!((
|
|
40
|
-
!!((
|
|
41
|
-
!!((
|
|
40
|
+
if (!!((_s = newConfig.forwardInboundCredentials) === null || _s === void 0 ? void 0 : _s.accessToken) !==
|
|
41
|
+
!!((_t = config.forwardInboundCredentials) === null || _t === void 0 ? void 0 : _t.accessToken) ||
|
|
42
|
+
!!((_u = newConfig.forwardInboundCredentials) === null || _u === void 0 ? void 0 : _u.idToken) !==
|
|
43
|
+
!!((_v = config.forwardInboundCredentials) === null || _v === void 0 ? void 0 : _v.idToken) ||
|
|
44
|
+
!!((_w = newConfig.forwardInboundCredentials) === null || _w === void 0 ? void 0 : _w.refreshToken) !==
|
|
45
|
+
!!((_x = config.forwardInboundCredentials) === null || _x === void 0 ? void 0 : _x.refreshToken)) {
|
|
42
46
|
return true;
|
|
43
47
|
}
|
|
44
48
|
return false;
|
|
@@ -51,11 +55,24 @@ class AuthBlockingService {
|
|
|
51
55
|
functionUri: endpoint.uri,
|
|
52
56
|
} });
|
|
53
57
|
}
|
|
54
|
-
else {
|
|
58
|
+
else if (endpoint.blockingTrigger.eventType === events.v1.BEFORE_SIGN_IN_EVENT) {
|
|
55
59
|
newBlockingConfig.triggers = Object.assign(Object.assign({}, newBlockingConfig.triggers), { beforeSignIn: {
|
|
56
60
|
functionUri: endpoint.uri,
|
|
57
61
|
} });
|
|
58
62
|
}
|
|
63
|
+
else if (endpoint.blockingTrigger.eventType === events.v1.BEFORE_SEND_EMAIL_EVENT) {
|
|
64
|
+
newBlockingConfig.triggers = Object.assign(Object.assign({}, newBlockingConfig.triggers), { beforeSendEmail: {
|
|
65
|
+
functionUri: endpoint.uri,
|
|
66
|
+
} });
|
|
67
|
+
}
|
|
68
|
+
else if (endpoint.blockingTrigger.eventType === events.v1.BEFORE_SEND_SMS_EVENT) {
|
|
69
|
+
newBlockingConfig.triggers = Object.assign(Object.assign({}, newBlockingConfig.triggers), { beforeSendSms: {
|
|
70
|
+
functionUri: endpoint.uri,
|
|
71
|
+
} });
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
throw new error_1.FirebaseError(`Received invalid blocking trigger event type ${endpoint.blockingTrigger.eventType}`);
|
|
75
|
+
}
|
|
59
76
|
newBlockingConfig.forwardInboundCredentials = Object.assign(Object.assign({}, oldBlockingConfig.forwardInboundCredentials), endpoint.blockingTrigger.options);
|
|
60
77
|
if (!this.configChanged(newBlockingConfig, oldBlockingConfig)) {
|
|
61
78
|
return;
|
|
@@ -70,17 +87,25 @@ class AuthBlockingService {
|
|
|
70
87
|
return this.triggerQueue;
|
|
71
88
|
}
|
|
72
89
|
async unregisterTriggerLocked(endpoint) {
|
|
73
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
90
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
74
91
|
const blockingConfig = await identityPlatform.getBlockingFunctionsConfig(endpoint.project);
|
|
75
92
|
if (endpoint.uri !== ((_b = (_a = blockingConfig.triggers) === null || _a === void 0 ? void 0 : _a.beforeCreate) === null || _b === void 0 ? void 0 : _b.functionUri) &&
|
|
76
|
-
endpoint.uri !== ((_d = (_c = blockingConfig.triggers) === null || _c === void 0 ? void 0 : _c.beforeSignIn) === null || _d === void 0 ? void 0 : _d.functionUri)
|
|
93
|
+
endpoint.uri !== ((_d = (_c = blockingConfig.triggers) === null || _c === void 0 ? void 0 : _c.beforeSignIn) === null || _d === void 0 ? void 0 : _d.functionUri) &&
|
|
94
|
+
endpoint.uri !== ((_f = (_e = blockingConfig.triggers) === null || _e === void 0 ? void 0 : _e.beforeSendEmail) === null || _f === void 0 ? void 0 : _f.functionUri) &&
|
|
95
|
+
endpoint.uri !== ((_h = (_g = blockingConfig.triggers) === null || _g === void 0 ? void 0 : _g.beforeSendSms) === null || _h === void 0 ? void 0 : _h.functionUri)) {
|
|
77
96
|
return;
|
|
78
97
|
}
|
|
79
|
-
if (endpoint.uri === ((
|
|
80
|
-
(
|
|
98
|
+
if (endpoint.uri === ((_k = (_j = blockingConfig.triggers) === null || _j === void 0 ? void 0 : _j.beforeCreate) === null || _k === void 0 ? void 0 : _k.functionUri)) {
|
|
99
|
+
(_l = blockingConfig.triggers) === null || _l === void 0 ? true : delete _l.beforeCreate;
|
|
100
|
+
}
|
|
101
|
+
if (endpoint.uri === ((_o = (_m = blockingConfig.triggers) === null || _m === void 0 ? void 0 : _m.beforeSignIn) === null || _o === void 0 ? void 0 : _o.functionUri)) {
|
|
102
|
+
(_p = blockingConfig.triggers) === null || _p === void 0 ? true : delete _p.beforeSignIn;
|
|
103
|
+
}
|
|
104
|
+
if (endpoint.uri === ((_r = (_q = blockingConfig.triggers) === null || _q === void 0 ? void 0 : _q.beforeSendEmail) === null || _r === void 0 ? void 0 : _r.functionUri)) {
|
|
105
|
+
(_s = blockingConfig.triggers) === null || _s === void 0 ? true : delete _s.beforeSendEmail;
|
|
81
106
|
}
|
|
82
|
-
if (endpoint.uri === ((
|
|
83
|
-
(
|
|
107
|
+
if (endpoint.uri === ((_u = (_t = blockingConfig.triggers) === null || _t === void 0 ? void 0 : _t.beforeSendSms) === null || _u === void 0 ? void 0 : _u.functionUri)) {
|
|
108
|
+
(_v = blockingConfig.triggers) === null || _v === void 0 ? true : delete _v.beforeSendSms;
|
|
84
109
|
}
|
|
85
110
|
await identityPlatform.setBlockingFunctionsConfig(endpoint.project, blockingConfig);
|
|
86
111
|
}
|
|
@@ -94,6 +94,8 @@ const EVENT_SERVICE_MAPPING = {
|
|
|
94
94
|
"google.firebase.firebasealerts.alerts.v1.published": firebaseAlertsService,
|
|
95
95
|
"providers/cloud.auth/eventTypes/user.beforeCreate": authBlockingService,
|
|
96
96
|
"providers/cloud.auth/eventTypes/user.beforeSignIn": authBlockingService,
|
|
97
|
+
"providers/cloud.auth/eventTypes/user.beforeSendEmail": authBlockingService,
|
|
98
|
+
"providers/cloud.auth/eventTypes/user.beforeSendSms": authBlockingService,
|
|
97
99
|
"google.firebase.database.ref.v1.written": databaseService,
|
|
98
100
|
"google.firebase.database.ref.v1.created": databaseService,
|
|
99
101
|
"google.firebase.database.ref.v1.updated": databaseService,
|
|
@@ -9,8 +9,9 @@ class AppHostingEmulator {
|
|
|
9
9
|
this.args = args;
|
|
10
10
|
}
|
|
11
11
|
async start() {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const { hostname, port } = await (0, serve_1.start)({
|
|
13
|
+
startCommand: this.args.startCommandOverride,
|
|
14
|
+
});
|
|
14
15
|
this.args.options.host = hostname;
|
|
15
16
|
this.args.options.port = port;
|
|
16
17
|
}
|
|
@@ -7,21 +7,30 @@ const utils_1 = require("./utils");
|
|
|
7
7
|
const constants_1 = require("../constants");
|
|
8
8
|
const spawn_1 = require("../../init/spawn");
|
|
9
9
|
const config_1 = require("./config");
|
|
10
|
-
|
|
10
|
+
const utils_2 = require("./utils");
|
|
11
|
+
const types_1 = require("../types");
|
|
12
|
+
async function start(options) {
|
|
11
13
|
const hostname = constants_1.DEFAULT_HOST;
|
|
12
14
|
let port = constants_1.DEFAULT_PORTS.apphosting;
|
|
13
15
|
while (!(await availablePort(hostname, port))) {
|
|
14
16
|
port += 1;
|
|
15
17
|
}
|
|
16
|
-
serve(port);
|
|
18
|
+
serve(port, options === null || options === void 0 ? void 0 : options.startCommand);
|
|
17
19
|
return { hostname, port };
|
|
18
20
|
}
|
|
19
21
|
exports.start = start;
|
|
20
|
-
async function serve(port) {
|
|
22
|
+
async function serve(port, startCommand) {
|
|
21
23
|
const rootDir = process.cwd();
|
|
22
|
-
const packageManager = await (0, utils_1.discoverPackageManager)(rootDir);
|
|
23
24
|
const apphostingLocalConfig = await (0, config_1.getLocalAppHostingConfiguration)(rootDir);
|
|
24
|
-
|
|
25
|
+
const environmentVariablesToInject = Object.assign(Object.assign({}, apphostingLocalConfig.environmentVariables), { PORT: port.toString() });
|
|
26
|
+
if (startCommand) {
|
|
27
|
+
utils_2.logger.logLabeled("BULLET", types_1.Emulators.APPHOSTING, `running custom start command: '${startCommand}'`);
|
|
28
|
+
await (0, spawn_1.spawnWithCommandString)(startCommand, rootDir, environmentVariablesToInject);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const packageManager = await (0, utils_1.discoverPackageManager)(rootDir);
|
|
32
|
+
utils_2.logger.logLabeled("BULLET", types_1.Emulators.APPHOSTING, `starting app with: '${packageManager} run dev'`);
|
|
33
|
+
await (0, spawn_1.wrapSpawn)(packageManager, ["run", "dev"], rootDir, environmentVariablesToInject);
|
|
25
34
|
}
|
|
26
35
|
function availablePort(host, port) {
|
|
27
36
|
return (0, portUtils_1.checkListenable)({
|
|
@@ -166,7 +166,7 @@ function findExportMetadata(importPath) {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
async function startAll(options, showUI = true, runningTestScript = false) {
|
|
169
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
169
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
170
170
|
const targets = filterEmulatorTargets(options);
|
|
171
171
|
options.targets = targets;
|
|
172
172
|
const singleProjectModeEnabled = ((_a = options.config.src.emulators) === null || _a === void 0 ? void 0 : _a.singleProjectMode) === undefined ||
|
|
@@ -208,9 +208,18 @@ async function startAll(options, showUI = true, runningTestScript = false) {
|
|
|
208
208
|
const emulatableBackends = [];
|
|
209
209
|
let extensionEmulator = undefined;
|
|
210
210
|
if (shouldStart(options, types_1.Emulators.EXTENSIONS)) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
let projectNumber = constants_1.Constants.FAKE_PROJECT_NUMBER;
|
|
212
|
+
if (!isDemoProject) {
|
|
213
|
+
try {
|
|
214
|
+
projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.EXTENSIONS).logLabeled("ERROR", types_1.Emulators.EXTENSIONS, `Unable to look up project number for ${options.project}.\n` +
|
|
218
|
+
" If this is a real project, ensure that you are logged in and have access to it.\n" +
|
|
219
|
+
" If this is a fake project, please use a project ID starting with 'demo-' to skip production calls.\n" +
|
|
220
|
+
" Continuing with a fake project number - secrets and other features that require production access may behave unexpectedly.");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
214
223
|
const aliases = (0, projectUtils_1.getAliases)(options, projectId);
|
|
215
224
|
extensionEmulator = new extensionsEmulator_1.ExtensionsEmulator({
|
|
216
225
|
options,
|
|
@@ -592,11 +601,13 @@ async function startAll(options, showUI = true, runningTestScript = false) {
|
|
|
592
601
|
await startEmulator(hostingEmulator);
|
|
593
602
|
}
|
|
594
603
|
if (experiments.isEnabled("emulatorapphosting")) {
|
|
604
|
+
const apphostingConfig = (_l = options.config.src.emulators) === null || _l === void 0 ? void 0 : _l[types_1.Emulators.APPHOSTING];
|
|
595
605
|
if (listenForEmulator.apphosting) {
|
|
596
606
|
const apphostingAddr = legacyGetFirstAddr(types_1.Emulators.APPHOSTING);
|
|
597
607
|
const apphostingEmulator = new apphosting_1.AppHostingEmulator({
|
|
598
608
|
host: apphostingAddr.host,
|
|
599
609
|
port: apphostingAddr.port,
|
|
610
|
+
startCommandOverride: apphostingConfig === null || apphostingConfig === void 0 ? void 0 : apphostingConfig.startCommandOverride,
|
|
600
611
|
options,
|
|
601
612
|
});
|
|
602
613
|
await startEmulator(apphostingEmulator);
|
|
@@ -48,20 +48,20 @@ const EMULATOR_UPDATE_DETAILS = {
|
|
|
48
48
|
},
|
|
49
49
|
dataconnect: process.platform === "darwin"
|
|
50
50
|
? {
|
|
51
|
-
version: "1.5.
|
|
52
|
-
expectedSize:
|
|
53
|
-
expectedChecksum: "
|
|
51
|
+
version: "1.5.1",
|
|
52
|
+
expectedSize: 25289472,
|
|
53
|
+
expectedChecksum: "92c425072db66c7e2cfa40b703ed807b",
|
|
54
54
|
}
|
|
55
55
|
: process.platform === "win32"
|
|
56
56
|
? {
|
|
57
|
-
version: "1.5.
|
|
58
|
-
expectedSize:
|
|
59
|
-
expectedChecksum: "
|
|
57
|
+
version: "1.5.1",
|
|
58
|
+
expectedSize: 25720320,
|
|
59
|
+
expectedChecksum: "2a5c654770233b740980d5f98f24be73",
|
|
60
60
|
}
|
|
61
61
|
: {
|
|
62
|
-
version: "1.5.
|
|
63
|
-
expectedSize:
|
|
64
|
-
expectedChecksum: "
|
|
62
|
+
version: "1.5.1",
|
|
63
|
+
expectedSize: 25202840,
|
|
64
|
+
expectedChecksum: "f95156cbcac237268791638ea0eb10e7",
|
|
65
65
|
},
|
|
66
66
|
};
|
|
67
67
|
exports.DownloadDetails = {
|
|
@@ -7,6 +7,7 @@ const types_1 = require("./types");
|
|
|
7
7
|
const events_1 = require("events");
|
|
8
8
|
const emulatorLogger_1 = require("./emulatorLogger");
|
|
9
9
|
const error_1 = require("../error");
|
|
10
|
+
const discovery_1 = require("../deploy/functions/runtimes/discovery");
|
|
10
11
|
var RuntimeWorkerState;
|
|
11
12
|
(function (RuntimeWorkerState) {
|
|
12
13
|
RuntimeWorkerState["CREATED"] = "CREATED";
|
|
@@ -187,7 +188,7 @@ class RuntimeWorker {
|
|
|
187
188
|
const timeout = new Promise((resolve, reject) => {
|
|
188
189
|
setTimeout(() => {
|
|
189
190
|
reject(new error_1.FirebaseError("Failed to load function."));
|
|
190
|
-
}, 30000);
|
|
191
|
+
}, (0, discovery_1.getFunctionDiscoveryTimeout)() || 30000);
|
|
191
192
|
});
|
|
192
193
|
while (true) {
|
|
193
194
|
try {
|
|
@@ -11,7 +11,7 @@ const registry_1 = require("./registry");
|
|
|
11
11
|
const error_1 = require("../error");
|
|
12
12
|
const hub_1 = require("./hub");
|
|
13
13
|
const downloadableEmulators_1 = require("./downloadableEmulators");
|
|
14
|
-
const
|
|
14
|
+
const node_fs_1 = require("node:fs");
|
|
15
15
|
const track_1 = require("../track");
|
|
16
16
|
class HubExport {
|
|
17
17
|
constructor(projectId, options) {
|
|
@@ -25,7 +25,14 @@ class HubExport {
|
|
|
25
25
|
if (!fs.existsSync(metadataPath)) {
|
|
26
26
|
return undefined;
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
let mdString = "";
|
|
29
|
+
try {
|
|
30
|
+
mdString = fs.readFileSync(metadataPath, "utf8").toString();
|
|
31
|
+
return JSON.parse(mdString);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
throw new error_1.FirebaseError(`Unable to parse metadata file ${metadataPath}: ${mdString}`);
|
|
35
|
+
}
|
|
29
36
|
}
|
|
30
37
|
async exportAll() {
|
|
31
38
|
const toExport = types_1.ALL_EMULATORS.filter(shouldExport);
|
|
@@ -74,7 +81,7 @@ class HubExport {
|
|
|
74
81
|
const metadataPath = path.join(this.tmpDir, HubExport.METADATA_FILE_NAME);
|
|
75
82
|
fs.writeFileSync(metadataPath, JSON.stringify(metadata, undefined, 2));
|
|
76
83
|
logger_1.logger.debug(`hubExport: swapping ${this.tmpDir} with ${this.exportPath}`);
|
|
77
|
-
|
|
84
|
+
(0, node_fs_1.rmSync)(this.exportPath, { recursive: true });
|
|
78
85
|
fse.moveSync(this.tmpDir, this.exportPath);
|
|
79
86
|
}
|
|
80
87
|
async exportFirestore(metadata) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Persistence = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
|
-
const
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const fse = require("fs-extra");
|
|
8
8
|
const path = require("path");
|
|
@@ -57,7 +57,7 @@ class Persistence {
|
|
|
57
57
|
this._diskPathMap.delete(fileName);
|
|
58
58
|
}
|
|
59
59
|
async deleteAll() {
|
|
60
|
-
await (0,
|
|
60
|
+
await (0, promises_1.rm)(this._dirPath, { recursive: true });
|
|
61
61
|
this._diskPathMap = new Map();
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
@@ -98,9 +98,18 @@ async function getFirebaseProjectParams(projectId, emulatorMode = false) {
|
|
|
98
98
|
const body = emulatorMode
|
|
99
99
|
? await (0, adminSdkConfig_1.getProjectAdminSdkConfigOrCached)(projectId)
|
|
100
100
|
: await (0, functionsConfig_1.getFirebaseConfig)({ project: projectId });
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
let projectNumber = constants_1.Constants.FAKE_PROJECT_NUMBER;
|
|
102
|
+
if (!constants_1.Constants.isDemoProject(projectId)) {
|
|
103
|
+
try {
|
|
104
|
+
projectNumber = await (0, getProjectNumber_1.getProjectNumber)({ projectId });
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
(0, utils_2.logLabeledError)("extensions", `Unable to look up project number for ${projectId}.\n` +
|
|
108
|
+
" If this is a real project, ensure that you are logged in and have access to it.\n" +
|
|
109
|
+
" If this is a fake project, please use a project ID starting with 'demo-' to skip production calls.\n" +
|
|
110
|
+
" Continuing with a fake project number - secrets and other features that require production access may behave unexpectedly.");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
104
113
|
const databaseURL = (_a = body === null || body === void 0 ? void 0 : body.databaseURL) !== null && _a !== void 0 ? _a : `https://${projectId}.firebaseio.com`;
|
|
105
114
|
const storageBucket = (_b = body === null || body === void 0 ? void 0 : body.storageBucket) !== null && _b !== void 0 ? _b : `${projectId}.appspot.com`;
|
|
106
115
|
const FIREBASE_CONFIG = JSON.stringify({
|
package/lib/firestore/delete.js
CHANGED
|
@@ -237,6 +237,17 @@ class FirestoreDelete {
|
|
|
237
237
|
}
|
|
238
238
|
queue.unshift(...toDelete);
|
|
239
239
|
}
|
|
240
|
+
else if (e.status === 429 &&
|
|
241
|
+
this.deleteBatchSize >= 10 &&
|
|
242
|
+
e.message.includes("database has exceeded their maximum bandwidth")) {
|
|
243
|
+
logger_1.logger.debug("Database has exceeded maximum write bandwidth", e);
|
|
244
|
+
const newBatchSize = Math.floor(toDelete.length / 2);
|
|
245
|
+
if (newBatchSize < this.deleteBatchSize) {
|
|
246
|
+
utils.logLabeledWarning("firestore", `delete rate exceeding maximum bandwidth, reducing batch size from ${this.deleteBatchSize} to ${newBatchSize}`);
|
|
247
|
+
this.setDeleteBatchSize(newBatchSize);
|
|
248
|
+
}
|
|
249
|
+
queue.unshift(...toDelete);
|
|
250
|
+
}
|
|
240
251
|
else if (e.status >= 500 && e.status < 600) {
|
|
241
252
|
logger_1.logger.debug("Server error deleting doc batch", e);
|
|
242
253
|
toDelete.forEach((doc) => {
|
|
@@ -18,7 +18,7 @@ exports.MAILING_LIST_URL = "https://goo.gle/41enW5X";
|
|
|
18
18
|
const DEFAULT_FIREBASE_FRAMEWORKS_VERSION = "^0.11.0";
|
|
19
19
|
exports.FIREBASE_FRAMEWORKS_VERSION = (experiments.isEnabled("internaltesting") && process.env.FIREBASE_FRAMEWORKS_VERSION) ||
|
|
20
20
|
DEFAULT_FIREBASE_FRAMEWORKS_VERSION;
|
|
21
|
-
exports.FIREBASE_FUNCTIONS_VERSION = "^
|
|
21
|
+
exports.FIREBASE_FUNCTIONS_VERSION = "^6.0.1";
|
|
22
22
|
exports.FIREBASE_ADMIN_VERSION = "^11.11.1";
|
|
23
23
|
exports.SHARP_VERSION = "^0.32 || ^0.33";
|
|
24
24
|
exports.NODE_VERSION = parseInt(process.versions.node, 10);
|
|
@@ -4,8 +4,6 @@ exports.ɵcodegenPublicDirectory = exports.build = exports.init = exports.discov
|
|
|
4
4
|
const cross_spawn_1 = require("cross-spawn");
|
|
5
5
|
const fs_extra_1 = require("fs-extra");
|
|
6
6
|
const path_1 = require("path");
|
|
7
|
-
const yaml = require("yaml");
|
|
8
|
-
const promises_1 = require("fs/promises");
|
|
9
7
|
const error_1 = require("../../error");
|
|
10
8
|
const utils_1 = require("./utils");
|
|
11
9
|
const constants_1 = require("./constants");
|
|
@@ -18,8 +16,7 @@ async function discover(dir) {
|
|
|
18
16
|
return;
|
|
19
17
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "web"))))
|
|
20
18
|
return;
|
|
21
|
-
const
|
|
22
|
-
const pubSpec = yaml.parse(pubSpecBuffer.toString());
|
|
19
|
+
const pubSpec = await (0, utils_1.getPubSpec)(dir);
|
|
23
20
|
const usingFlutter = (_a = pubSpec.dependencies) === null || _a === void 0 ? void 0 : _a.flutter;
|
|
24
21
|
if (!usingFlutter)
|
|
25
22
|
return;
|
|
@@ -44,9 +41,12 @@ function init(setup, config) {
|
|
|
44
41
|
return Promise.resolve();
|
|
45
42
|
}
|
|
46
43
|
exports.init = init;
|
|
47
|
-
function build(cwd) {
|
|
44
|
+
async function build(cwd) {
|
|
48
45
|
(0, utils_1.assertFlutterCliExists)();
|
|
49
|
-
const
|
|
46
|
+
const pubSpec = await (0, utils_1.getPubSpec)(cwd);
|
|
47
|
+
const otherArgs = (0, utils_1.getAdditionalBuildArgs)(pubSpec);
|
|
48
|
+
const buildArgs = ["build", "web", ...otherArgs].filter(Boolean);
|
|
49
|
+
const build = (0, cross_spawn_1.sync)("flutter", buildArgs, { cwd, stdio: "inherit" });
|
|
50
50
|
if (build.status !== 0)
|
|
51
51
|
throw new error_1.FirebaseError("Unable to build your Flutter app");
|
|
52
52
|
return Promise.resolve({ wantsBackend: false });
|
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertFlutterCliExists = void 0;
|
|
3
|
+
exports.getPubSpec = exports.getAdditionalBuildArgs = exports.assertFlutterCliExists = void 0;
|
|
4
4
|
const cross_spawn_1 = require("cross-spawn");
|
|
5
5
|
const error_1 = require("../../error");
|
|
6
|
+
const promises_1 = require("fs/promises");
|
|
7
|
+
const fs_extra_1 = require("fs-extra");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const yaml = require("yaml");
|
|
6
10
|
function assertFlutterCliExists() {
|
|
7
11
|
const process = (0, cross_spawn_1.sync)("flutter", ["--version"], { stdio: "ignore" });
|
|
8
12
|
if (process.status !== 0)
|
|
9
13
|
throw new error_1.FirebaseError("Flutter CLI not found, follow the instructions here https://docs.flutter.dev/get-started/install before trying again.");
|
|
10
14
|
}
|
|
11
15
|
exports.assertFlutterCliExists = assertFlutterCliExists;
|
|
16
|
+
function getAdditionalBuildArgs(pubSpec) {
|
|
17
|
+
const treeShakePackages = [
|
|
18
|
+
"material_icons_named",
|
|
19
|
+
"material_symbols_icons",
|
|
20
|
+
"material_design_icons_flutter",
|
|
21
|
+
"flutter_iconpicker",
|
|
22
|
+
"font_awesome_flutter",
|
|
23
|
+
"ionicons_named",
|
|
24
|
+
];
|
|
25
|
+
const hasTreeShakePackage = treeShakePackages.some((pkg) => { var _a; return (_a = pubSpec.dependencies) === null || _a === void 0 ? void 0 : _a[pkg]; });
|
|
26
|
+
const treeShakeFlags = hasTreeShakePackage ? ["--no-tree-shake-icons"] : [];
|
|
27
|
+
return [...treeShakeFlags];
|
|
28
|
+
}
|
|
29
|
+
exports.getAdditionalBuildArgs = getAdditionalBuildArgs;
|
|
30
|
+
async function getPubSpec(dir) {
|
|
31
|
+
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "pubspec.yaml"))))
|
|
32
|
+
return {};
|
|
33
|
+
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "web"))))
|
|
34
|
+
return {};
|
|
35
|
+
try {
|
|
36
|
+
const pubSpecBuffer = await (0, promises_1.readFile)((0, path_1.join)(dir, "pubspec.yaml"));
|
|
37
|
+
return yaml.parse(pubSpecBuffer.toString());
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.info("Failed to read pubspec.yaml");
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.getPubSpec = getPubSpec;
|
|
@@ -7,8 +7,12 @@ exports.BLOCKING_LABEL = "deployment-blocking";
|
|
|
7
7
|
exports.BLOCKING_LABEL_KEY_TO_EVENT = {
|
|
8
8
|
"before-create": "providers/cloud.auth/eventTypes/user.beforeCreate",
|
|
9
9
|
"before-sign-in": "providers/cloud.auth/eventTypes/user.beforeSignIn",
|
|
10
|
+
"before-send-email": "providers/cloud.auth/eventTypes/user.beforeSendEmail",
|
|
11
|
+
"before-send-sms": "providers/cloud.auth/eventTypes/user.beforeSendSms",
|
|
10
12
|
};
|
|
11
13
|
exports.BLOCKING_EVENT_TO_LABEL_KEY = {
|
|
12
14
|
"providers/cloud.auth/eventTypes/user.beforeCreate": "before-create",
|
|
13
15
|
"providers/cloud.auth/eventTypes/user.beforeSignIn": "before-sign-in",
|
|
16
|
+
"providers/cloud.auth/eventTypes/user.beforeSendEmail": "before-send-email",
|
|
17
|
+
"providers/cloud.auth/eventTypes/user.beforeSendSms": "before-send-sms",
|
|
14
18
|
};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AUTH_BLOCKING_EVENTS = exports.BEFORE_SIGN_IN_EVENT = exports.BEFORE_CREATE_EVENT = void 0;
|
|
3
|
+
exports.AUTH_BLOCKING_EVENTS = exports.BEFORE_SEND_SMS_EVENT = exports.BEFORE_SEND_EMAIL_EVENT = exports.BEFORE_SIGN_IN_EVENT = exports.BEFORE_CREATE_EVENT = void 0;
|
|
4
4
|
exports.BEFORE_CREATE_EVENT = "providers/cloud.auth/eventTypes/user.beforeCreate";
|
|
5
5
|
exports.BEFORE_SIGN_IN_EVENT = "providers/cloud.auth/eventTypes/user.beforeSignIn";
|
|
6
|
-
exports.
|
|
6
|
+
exports.BEFORE_SEND_EMAIL_EVENT = "providers/cloud.auth/eventTypes/user.beforeSendEmail";
|
|
7
|
+
exports.BEFORE_SEND_SMS_EVENT = "providers/cloud.auth/eventTypes/user.beforeSendSms";
|
|
8
|
+
exports.AUTH_BLOCKING_EVENTS = [
|
|
9
|
+
exports.BEFORE_CREATE_EVENT,
|
|
10
|
+
exports.BEFORE_SIGN_IN_EVENT,
|
|
11
|
+
exports.BEFORE_SEND_EMAIL_EVENT,
|
|
12
|
+
exports.BEFORE_SEND_SMS_EVENT,
|
|
13
|
+
];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interactiveExecuteQuery = exports.confirmDangerousQuery = void 0;
|
|
4
|
+
const ora = require("ora");
|
|
5
|
+
const clc = require("colorette");
|
|
6
|
+
const logger_1 = require("../../logger");
|
|
7
|
+
const prompt_1 = require("../../prompt");
|
|
8
|
+
const Table = require("cli-table");
|
|
9
|
+
const destructiveSqlKeywords = ["DROP", "DELETE"];
|
|
10
|
+
function checkIsDestructiveSql(query) {
|
|
11
|
+
const upperCaseQuery = query.toUpperCase();
|
|
12
|
+
return destructiveSqlKeywords.some((keyword) => upperCaseQuery.includes(keyword.toUpperCase()));
|
|
13
|
+
}
|
|
14
|
+
async function confirmDangerousQuery(query) {
|
|
15
|
+
if (checkIsDestructiveSql(query)) {
|
|
16
|
+
return await (0, prompt_1.confirm)({
|
|
17
|
+
message: clc.yellow("This query may be destructive. Are you sure you want to proceed?"),
|
|
18
|
+
default: false,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
exports.confirmDangerousQuery = confirmDangerousQuery;
|
|
24
|
+
async function interactiveExecuteQuery(query, conn) {
|
|
25
|
+
const spinner = ora("Executing query...").start();
|
|
26
|
+
try {
|
|
27
|
+
const results = await conn.query(query);
|
|
28
|
+
spinner.succeed(clc.green("Query executed successfully"));
|
|
29
|
+
if (Array.isArray(results.rows) && results.rows.length > 0) {
|
|
30
|
+
const table = new Table({
|
|
31
|
+
head: Object.keys(results.rows[0]).map((key) => clc.cyan(key)),
|
|
32
|
+
style: { head: [], border: [] },
|
|
33
|
+
});
|
|
34
|
+
for (const row of results.rows) {
|
|
35
|
+
table.push(Object.values(row));
|
|
36
|
+
}
|
|
37
|
+
logger_1.logger.info(table.toString());
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (query.toUpperCase().includes("SELECT")) {
|
|
41
|
+
logger_1.logger.info(clc.yellow("No results returned"));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
spinner.fail(clc.red(`Failed executing query: ${err}`));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.interactiveExecuteQuery = interactiveExecuteQuery;
|
package/lib/gcp/firestore.js
CHANGED
|
@@ -62,7 +62,11 @@ async function deleteDocuments(project, docs, allowEmulator = false) {
|
|
|
62
62
|
return { delete: doc.name };
|
|
63
63
|
});
|
|
64
64
|
const data = { writes };
|
|
65
|
-
const res = await apiClient.post(url, data
|
|
65
|
+
const res = await apiClient.post(url, data, {
|
|
66
|
+
retries: 10,
|
|
67
|
+
retryCodes: [429, 409, 503],
|
|
68
|
+
retryMaxTimeout: 20 * 1000,
|
|
69
|
+
});
|
|
66
70
|
return res.body.writeResults.length;
|
|
67
71
|
}
|
|
68
72
|
exports.deleteDocuments = deleteDocuments;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.doSetup = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const apiv2_1 = require("../../../apiv2");
|
|
8
8
|
const github_1 = require("./github");
|
|
@@ -116,7 +116,7 @@ async function doSetup(setup, config, options) {
|
|
|
116
116
|
choices,
|
|
117
117
|
}, setup.hosting);
|
|
118
118
|
if (discoveredFramework)
|
|
119
|
-
(0,
|
|
119
|
+
(0, node_fs_1.rmSync)(setup.hosting.source, { recursive: true });
|
|
120
120
|
await frameworks_1.WebFrameworks[setup.hosting.whichFramework].init(setup, config);
|
|
121
121
|
}
|
|
122
122
|
await (0, prompt_1.promptOnce)({
|
package/lib/init/spawn.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.wrapSpawn = void 0;
|
|
3
|
+
exports.spawnWithCommandString = exports.wrapSpawn = void 0;
|
|
4
4
|
const spawn = require("cross-spawn");
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
6
|
function wrapSpawn(cmd, args, projectDir, environmentVariables) {
|
|
@@ -22,3 +22,23 @@ function wrapSpawn(cmd, args, projectDir, environmentVariables) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
exports.wrapSpawn = wrapSpawn;
|
|
25
|
+
function spawnWithCommandString(cmd, projectDir, environmentVariables) {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const installer = spawn(cmd, {
|
|
28
|
+
cwd: projectDir,
|
|
29
|
+
stdio: "inherit",
|
|
30
|
+
shell: true,
|
|
31
|
+
env: Object.assign(Object.assign({}, process.env), environmentVariables),
|
|
32
|
+
});
|
|
33
|
+
installer.on("error", (err) => {
|
|
34
|
+
logger_1.logger.log("DEBUG", err.stack);
|
|
35
|
+
});
|
|
36
|
+
installer.on("close", (code) => {
|
|
37
|
+
if (code === 0) {
|
|
38
|
+
return resolve();
|
|
39
|
+
}
|
|
40
|
+
return reject();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
exports.spawnWithCommandString = spawnWithCommandString;
|
package/lib/requireAuth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.requireAuth = void 0;
|
|
3
|
+
exports.requireAuth = exports.refreshAuth = void 0;
|
|
4
4
|
const google_auth_library_1 = require("google-auth-library");
|
|
5
5
|
const clc = require("colorette");
|
|
6
6
|
const api = require("./api");
|
|
@@ -12,6 +12,7 @@ const scopes = require("./scopes");
|
|
|
12
12
|
const auth_1 = require("./auth");
|
|
13
13
|
const AUTH_ERROR_MESSAGE = `Command requires authentication, please run ${clc.bold("firebase login")}`;
|
|
14
14
|
let authClient;
|
|
15
|
+
let lastOptions;
|
|
15
16
|
function getAuthClient(config) {
|
|
16
17
|
if (authClient) {
|
|
17
18
|
return authClient;
|
|
@@ -46,7 +47,16 @@ async function autoAuth(options, authScopes) {
|
|
|
46
47
|
}
|
|
47
48
|
return clientEmail;
|
|
48
49
|
}
|
|
50
|
+
async function refreshAuth() {
|
|
51
|
+
if (!lastOptions) {
|
|
52
|
+
throw new error_1.FirebaseError("Unable to refresh auth: not yet authenticated.");
|
|
53
|
+
}
|
|
54
|
+
await requireAuth(lastOptions);
|
|
55
|
+
return lastOptions.tokens;
|
|
56
|
+
}
|
|
57
|
+
exports.refreshAuth = refreshAuth;
|
|
49
58
|
async function requireAuth(options) {
|
|
59
|
+
lastOptions = options;
|
|
50
60
|
api.setScopes([scopes.CLOUD_PLATFORM, scopes.FIREBASE_PLATFORM]);
|
|
51
61
|
options.authScopes = api.getScopes();
|
|
52
62
|
const tokens = options.tokens;
|
package/lib/responseToError.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.responseToError = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const error_1 = require("./error");
|
|
6
|
-
function responseToError(response, body) {
|
|
6
|
+
function responseToError(response, body, url) {
|
|
7
7
|
if (response.statusCode < 400) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
@@ -37,7 +37,10 @@ function responseToError(response, body) {
|
|
|
37
37
|
message: errMessage,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
let message = "HTTP Error: " + response.statusCode + ", " + (body.error.message || body.error);
|
|
41
|
+
if (url) {
|
|
42
|
+
message = "Request to " + url + " had " + message;
|
|
43
|
+
}
|
|
41
44
|
let exitCode;
|
|
42
45
|
if (response.statusCode >= 500) {
|
|
43
46
|
exitCode = 2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-tools",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.23.0",
|
|
4
4
|
"description": "Command-Line Interface for Firebase",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -110,7 +110,6 @@
|
|
|
110
110
|
"progress": "^2.0.3",
|
|
111
111
|
"proxy-agent": "^6.3.0",
|
|
112
112
|
"retry": "^0.13.1",
|
|
113
|
-
"rimraf": "^5.0.0",
|
|
114
113
|
"semver": "^7.5.2",
|
|
115
114
|
"sql-formatter": "^15.3.0",
|
|
116
115
|
"stream-chain": "^2.2.4",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"main": "lib/index.js",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"firebase-admin": "^12.
|
|
19
|
-
"firebase-functions": "^
|
|
18
|
+
"firebase-admin": "^12.6.0",
|
|
19
|
+
"firebase-functions": "^6.0.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@typescript-eslint/eslint-plugin": "^5.12.0",
|