firebase-tools 14.3.1 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api.js +10 -2
- package/lib/apphosting/backend.js +72 -18
- package/lib/apphosting/rollout.js +2 -2
- package/lib/apphosting/secrets/dialogs.js +4 -4
- package/lib/apphosting/secrets/index.js +2 -2
- package/lib/auth.js +22 -2
- package/lib/bin/cli.js +1 -33
- package/lib/bin/mcp.js +12 -2
- package/lib/checkValidTargetFilters.js +1 -0
- package/lib/command.js +3 -2
- package/lib/commands/apphosting-secrets-grantaccess.js +1 -1
- package/lib/commands/deploy.js +1 -0
- package/lib/commands/init.js +1 -1
- package/lib/commands/login-use.js +2 -11
- package/lib/commands/use.js +9 -8
- package/lib/config.js +1 -0
- package/lib/crashlytics/listTopIssues.js +44 -0
- package/lib/dataconnect/cloudAICompanionClient.js +67 -0
- package/lib/deploy/apphosting/args.js +2 -0
- package/lib/deploy/apphosting/deploy.js +74 -0
- package/lib/deploy/apphosting/index.js +9 -0
- package/lib/deploy/apphosting/prepare.js +141 -0
- package/lib/deploy/apphosting/release.js +53 -0
- package/lib/deploy/apphosting/util.js +65 -0
- package/lib/deploy/extensions/v2FunctionHelper.js +2 -1
- package/lib/deploy/functions/checkIam.js +3 -3
- package/lib/deploy/functions/ensure.js +2 -1
- package/lib/deploy/functions/prepare.js +23 -16
- package/lib/deploy/functions/release/fabricator.js +4 -4
- package/lib/deploy/functions/release/index.js +1 -1
- package/lib/deploy/functions/runtimes/python/index.js +3 -0
- package/lib/deploy/functions/runtimes/supported/types.js +17 -11
- package/lib/deploy/index.js +2 -0
- package/lib/emulator/apphosting/index.js +1 -0
- package/lib/emulator/apphosting/serve.js +77 -3
- package/lib/emulator/auth/widget_ui.js +2 -1
- package/lib/emulator/controller.js +18 -4
- package/lib/emulator/dataconnectEmulator.js +9 -2
- package/lib/emulator/downloadableEmulatorInfo.json +60 -0
- package/lib/emulator/downloadableEmulators.js +25 -61
- package/lib/experiments.js +1 -1
- package/lib/extensions/manifest.js +2 -2
- package/lib/fsAsync.js +9 -2
- package/lib/gcp/auth.js +32 -2
- package/lib/gcp/cloudbilling.js +12 -1
- package/lib/gcp/cloudfunctions.js +1 -2
- package/lib/gcp/cloudfunctionsv2.js +1 -2
- package/lib/gcp/cloudscheduler.js +2 -2
- package/lib/gcp/computeEngine.js +19 -2
- package/lib/gcp/devConnect.js +6 -1
- package/lib/gcp/firestore.js +24 -1
- package/lib/gcp/iam.js +1 -5
- package/lib/gcp/storage.js +25 -1
- package/lib/index.js +1 -2
- package/lib/init/features/apphosting.js +84 -6
- package/lib/init/features/database.js +64 -45
- package/lib/init/features/dataconnect/index.js +51 -53
- package/lib/init/features/emulators.js +8 -4
- package/lib/init/features/firestore/index.js +54 -23
- package/lib/init/features/firestore/indexes.js +23 -24
- package/lib/init/features/firestore/rules.js +35 -41
- package/lib/init/features/functions/index.js +2 -0
- package/lib/init/features/functions/javascript.js +3 -2
- package/lib/init/features/functions/typescript.js +3 -2
- package/lib/init/features/genkit/index.js +2 -1
- package/lib/init/features/hosting/github.js +3 -2
- package/lib/init/features/index.js +8 -4
- package/lib/init/features/remoteconfig.js +3 -2
- package/lib/init/index.js +76 -24
- package/lib/logger.js +71 -7
- package/lib/management/projects.js +24 -1
- package/lib/mcp/errors.js +1 -1
- package/lib/mcp/index.js +135 -43
- package/lib/mcp/tools/auth/get_user.js +16 -7
- package/lib/mcp/tools/auth/index.js +8 -1
- package/lib/mcp/tools/auth/list_users.js +47 -0
- package/lib/mcp/tools/auth/set_claims.js +20 -11
- package/lib/mcp/tools/auth/set_sms_region_policy.js +1 -1
- package/lib/mcp/tools/core/consult_assistant.js +1 -1
- package/lib/mcp/tools/core/create_android_sha.js +40 -0
- package/lib/mcp/tools/core/create_app.js +90 -0
- package/lib/mcp/tools/core/create_project.js +68 -0
- package/lib/mcp/tools/core/get_admin_sdk_config.js +26 -0
- package/lib/mcp/tools/core/get_environment.js +51 -0
- package/lib/mcp/tools/core/get_sdk_config.js +6 -3
- package/lib/mcp/tools/core/index.js +19 -2
- package/lib/mcp/tools/core/init.js +129 -0
- package/lib/mcp/tools/core/update_environment.js +55 -0
- package/lib/mcp/tools/crashlytics/index.js +5 -0
- package/lib/mcp/tools/crashlytics/list_top_issues.js +34 -0
- package/lib/mcp/tools/dataconnect/converter.js +13 -1
- package/lib/mcp/tools/dataconnect/emulator.js +32 -0
- package/lib/mcp/tools/dataconnect/execute_graphql.js +24 -8
- package/lib/mcp/tools/dataconnect/execute_graphql_read.js +24 -8
- package/lib/mcp/tools/dataconnect/execute_mutation.js +27 -15
- package/lib/mcp/tools/dataconnect/execute_query.js +26 -14
- package/lib/mcp/tools/dataconnect/generate_operation.js +6 -6
- package/lib/mcp/tools/dataconnect/generate_schema.js +1 -1
- package/lib/mcp/tools/dataconnect/get_connector.js +7 -7
- package/lib/mcp/tools/dataconnect/get_schema.js +5 -5
- package/lib/mcp/tools/dataconnect/index.js +1 -5
- package/lib/mcp/tools/dataconnect/list_services.js +1 -1
- package/lib/mcp/tools/firestore/converter.js +47 -1
- package/lib/mcp/tools/firestore/delete_document.js +37 -0
- package/lib/mcp/tools/firestore/index.js +12 -2
- package/lib/mcp/tools/firestore/list_collections.js +1 -6
- package/lib/mcp/tools/firestore/query_collection.js +116 -0
- package/lib/mcp/tools/index.js +35 -16
- package/lib/mcp/tools/messaging/index.js +5 -0
- package/lib/mcp/tools/messaging/send_message.js +42 -0
- package/lib/mcp/tools/remoteconfig/get_template.js +27 -0
- package/lib/mcp/tools/remoteconfig/index.js +7 -0
- package/lib/mcp/tools/remoteconfig/publish_template.js +34 -0
- package/lib/mcp/tools/remoteconfig/rollback_template.js +29 -0
- package/lib/mcp/tools/rules/get_rules.js +29 -0
- package/lib/mcp/tools/rules/validate_rules.js +98 -0
- package/lib/mcp/tools/storage/get_download_url.js +8 -5
- package/lib/mcp/tools/storage/index.js +7 -2
- package/lib/mcp/types.js +9 -1
- package/lib/mcp/util.js +29 -2
- package/lib/messaging/interfaces.js +2 -0
- package/lib/messaging/sendMessage.js +48 -0
- package/lib/remoteconfig/publish.js +39 -0
- package/lib/requireAuth.js +2 -2
- package/lib/utils.js +2 -37
- package/package.json +2 -1
- package/schema/firebase-config.json +62 -10
- package/templates/init/functions/javascript/package.lint.json +1 -1
- package/templates/init/functions/javascript/package.nolint.json +1 -1
- package/templates/init/functions/typescript/package.lint.json +1 -1
- package/templates/init/functions/typescript/package.nolint.json +2 -2
- package/lib/mcp/tools/directory/get_project_directory.js +0 -20
- package/lib/mcp/tools/directory/index.js +0 -6
- package/lib/mcp/tools/directory/set_project_directory.js +0 -33
- package/lib/mcp/tools/firestore/get_rules.js +0 -26
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.doSetup = void 0;
|
|
3
|
+
exports.actuate = exports.askQuestions = exports.doSetup = void 0;
|
|
4
4
|
const logger_1 = require("../../../logger");
|
|
5
5
|
const apiEnabled = require("../../../ensureApiEnabled");
|
|
6
6
|
const requirePermissions_1 = require("../../../requirePermissions");
|
|
@@ -10,42 +10,73 @@ const indexes = require("./indexes");
|
|
|
10
10
|
const error_1 = require("../../../error");
|
|
11
11
|
const clc = require("colorette");
|
|
12
12
|
const prompt_1 = require("../../../prompt");
|
|
13
|
-
async function checkProjectSetup(setup,
|
|
13
|
+
async function checkProjectSetup(setup, options, info) {
|
|
14
14
|
const firestoreUnusedError = new error_1.FirebaseError(`It looks like you haven't used Cloud Firestore in this project before. Go to ${clc.bold(clc.underline(`https://console.firebase.google.com/project/${setup.projectId}/firestore`))} to create your Cloud Firestore database.`, { exit: 1 });
|
|
15
15
|
const isFirestoreEnabled = await apiEnabled.check(setup.projectId, "firestore.googleapis.com", "", true);
|
|
16
16
|
if (!isFirestoreEnabled) {
|
|
17
17
|
throw firestoreUnusedError;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
|
|
19
|
+
info.databaseId = info.databaseId || "(default)";
|
|
20
|
+
let dbType = await (0, checkDatabaseType_1.checkDatabaseType)(setup.projectId, info.databaseId);
|
|
21
|
+
if (dbType === "DATABASE_DOES_NOT_EXIST") {
|
|
22
|
+
info.databaseId = await selectDatabaseByPrompting();
|
|
23
|
+
dbType = await (0, checkDatabaseType_1.checkDatabaseType)(setup.projectId, info.databaseId);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
if (dbType !== "FIRESTORE_NATIVE") {
|
|
26
|
+
logger_1.logger.debug(`firestore database_type: ${dbType}`);
|
|
25
27
|
throw new error_1.FirebaseError(`It looks like this project is using Cloud Datastore or Cloud Firestore in Datastore mode. The Firebase CLI can only manage projects using Cloud Firestore in Native mode. For more information, visit https://cloud.google.com/datastore/docs/firestore-or-datastore`, { exit: 1 });
|
|
26
28
|
}
|
|
27
29
|
await (0, requirePermissions_1.requirePermissions)(Object.assign(Object.assign({}, options), { project: setup.projectId }));
|
|
28
30
|
}
|
|
29
|
-
async function getDatabaseType(setup) {
|
|
30
|
-
const dbType = await (0, checkDatabaseType_1.checkDatabaseType)(setup.projectId, setup.databaseId);
|
|
31
|
-
logger_1.logger.debug(`database_type: ${dbType}`);
|
|
32
|
-
if (dbType === "DATABASE_DOES_NOT_EXIST") {
|
|
33
|
-
setup.databaseId = await selectDatabaseByPrompting();
|
|
34
|
-
return await getDatabaseType(setup);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
return dbType;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
31
|
function selectDatabaseByPrompting() {
|
|
41
32
|
return (0, prompt_1.input)("Please input the name of the Native Firestore database you would like to use:");
|
|
42
33
|
}
|
|
43
34
|
async function doSetup(setup, config, options) {
|
|
35
|
+
await askQuestions(setup, config, options);
|
|
36
|
+
await actuate(setup, config);
|
|
37
|
+
}
|
|
38
|
+
exports.doSetup = doSetup;
|
|
39
|
+
async function askQuestions(setup, config, options) {
|
|
40
|
+
const firestore = !Array.isArray(setup.config.firestore) ? setup.config.firestore : undefined;
|
|
41
|
+
const info = {
|
|
42
|
+
databaseId: (firestore === null || firestore === void 0 ? void 0 : firestore.database) || "",
|
|
43
|
+
rulesFilename: (firestore === null || firestore === void 0 ? void 0 : firestore.rules) || "",
|
|
44
|
+
rules: "",
|
|
45
|
+
writeRules: true,
|
|
46
|
+
indexesFilename: (firestore === null || firestore === void 0 ? void 0 : firestore.indexes) || "",
|
|
47
|
+
indexes: "",
|
|
48
|
+
writeIndexes: true,
|
|
49
|
+
};
|
|
44
50
|
if (setup.projectId) {
|
|
45
|
-
await checkProjectSetup(setup,
|
|
51
|
+
await checkProjectSetup(setup, options, info);
|
|
46
52
|
}
|
|
47
|
-
setup
|
|
48
|
-
await
|
|
49
|
-
|
|
53
|
+
await rules.initRules(setup, config, info);
|
|
54
|
+
await indexes.initIndexes(setup, config, info);
|
|
55
|
+
setup.featureInfo = setup.featureInfo || {};
|
|
56
|
+
setup.featureInfo.firestore = info;
|
|
50
57
|
}
|
|
51
|
-
exports.
|
|
58
|
+
exports.askQuestions = askQuestions;
|
|
59
|
+
async function actuate(setup, config) {
|
|
60
|
+
var _a;
|
|
61
|
+
const info = (_a = setup.featureInfo) === null || _a === void 0 ? void 0 : _a.firestore;
|
|
62
|
+
if (!info) {
|
|
63
|
+
throw new error_1.FirebaseError("Firestore featureInfo is not found");
|
|
64
|
+
}
|
|
65
|
+
info.databaseId = info.databaseId || "(default)";
|
|
66
|
+
info.rules = info.rules || rules.getDefaultRules();
|
|
67
|
+
info.rulesFilename = info.rulesFilename || rules.DEFAULT_RULES_FILE;
|
|
68
|
+
info.indexes = info.indexes || indexes.INDEXES_TEMPLATE;
|
|
69
|
+
info.indexesFilename = info.indexesFilename || indexes.DEFAULT_INDEXES_FILE;
|
|
70
|
+
setup.config.firestore = {
|
|
71
|
+
database: info.databaseId,
|
|
72
|
+
rules: info.rulesFilename,
|
|
73
|
+
indexes: info.indexesFilename,
|
|
74
|
+
};
|
|
75
|
+
if (info.writeRules) {
|
|
76
|
+
config.writeProjectFile(info.rulesFilename, info.rules);
|
|
77
|
+
}
|
|
78
|
+
if (info.writeIndexes) {
|
|
79
|
+
config.writeProjectFile(info.indexesFilename, info.indexes);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.actuate = actuate;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initIndexes = void 0;
|
|
3
|
+
exports.initIndexes = exports.INDEXES_TEMPLATE = exports.DEFAULT_INDEXES_FILE = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const error_1 = require("../../../error");
|
|
6
6
|
const api = require("../../../firestore/api");
|
|
@@ -9,50 +9,49 @@ const prompt_1 = require("../../../prompt");
|
|
|
9
9
|
const logger_1 = require("../../../logger");
|
|
10
10
|
const templates_1 = require("../../../templates");
|
|
11
11
|
const indexes = new api.FirestoreApi();
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
exports.DEFAULT_INDEXES_FILE = "firestore.indexes.json";
|
|
13
|
+
exports.INDEXES_TEMPLATE = (0, templates_1.readTemplateSync)("init/firestore/firestore.indexes.json");
|
|
14
|
+
async function initIndexes(setup, config, info) {
|
|
14
15
|
logger_1.logger.info();
|
|
15
16
|
logger_1.logger.info("Firestore indexes allow you to perform complex queries while");
|
|
16
17
|
logger_1.logger.info("maintaining performance that scales with the size of the result");
|
|
17
18
|
logger_1.logger.info("set. You can keep index definitions in your project directory");
|
|
18
19
|
logger_1.logger.info("and publish them with " + clc.bold("firebase deploy") + ".");
|
|
19
20
|
logger_1.logger.info();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (fsutils.fileExistsSync(
|
|
21
|
+
info.indexesFilename =
|
|
22
|
+
info.indexesFilename ||
|
|
23
|
+
(await (0, prompt_1.input)({
|
|
24
|
+
message: "What file should be used for Firestore indexes?",
|
|
25
|
+
default: exports.DEFAULT_INDEXES_FILE,
|
|
26
|
+
}));
|
|
27
|
+
if (fsutils.fileExistsSync(info.indexesFilename)) {
|
|
27
28
|
const msg = "File " +
|
|
28
|
-
clc.bold(
|
|
29
|
+
clc.bold(info.indexesFilename) +
|
|
29
30
|
" already exists." +
|
|
30
31
|
" Do you want to overwrite it with the Firestore Indexes from the Firebase Console?";
|
|
31
32
|
if (!(await (0, prompt_1.confirm)(msg))) {
|
|
33
|
+
info.writeIndexes = false;
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
+
if (setup.projectId) {
|
|
38
|
+
info.indexes = await getIndexesFromConsole(setup.projectId, info.databaseId);
|
|
37
39
|
}
|
|
38
|
-
return getIndexesFromConsole(setup.projectId, setup.databaseId).then((contents) => {
|
|
39
|
-
return config.writeProjectFile(setup.config.firestore.indexes, contents);
|
|
40
|
-
});
|
|
41
40
|
}
|
|
42
41
|
exports.initIndexes = initIndexes;
|
|
43
|
-
function getIndexesFromConsole(projectId, databaseId) {
|
|
42
|
+
async function getIndexesFromConsole(projectId, databaseId) {
|
|
44
43
|
const indexesPromise = indexes.listIndexes(projectId, databaseId);
|
|
45
44
|
const fieldOverridesPromise = indexes.listFieldOverrides(projectId, databaseId);
|
|
46
|
-
|
|
47
|
-
.
|
|
48
|
-
return indexes.makeIndexSpec(res[0], res[1]);
|
|
49
|
-
}
|
|
50
|
-
|
|
45
|
+
try {
|
|
46
|
+
const res = await Promise.all([indexesPromise, fieldOverridesPromise]);
|
|
47
|
+
return JSON.stringify(indexes.makeIndexSpec(res[0], res[1]), null, 2);
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
51
50
|
if (e.message.indexOf("is not a Cloud Firestore enabled project") >= 0) {
|
|
52
|
-
return INDEXES_TEMPLATE;
|
|
51
|
+
return exports.INDEXES_TEMPLATE;
|
|
53
52
|
}
|
|
54
53
|
throw new error_1.FirebaseError("Error fetching Firestore indexes", {
|
|
55
54
|
original: e,
|
|
56
55
|
});
|
|
57
|
-
}
|
|
56
|
+
}
|
|
58
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initRules = void 0;
|
|
3
|
+
exports.initRules = exports.getDefaultRules = exports.DEFAULT_RULES_FILE = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
5
|
const gcp = require("../../../gcp");
|
|
6
6
|
const fsutils = require("../../../fsutils");
|
|
@@ -8,60 +8,54 @@ const prompt_1 = require("../../../prompt");
|
|
|
8
8
|
const logger_1 = require("../../../logger");
|
|
9
9
|
const utils = require("../../../utils");
|
|
10
10
|
const templates_1 = require("../../../templates");
|
|
11
|
-
|
|
11
|
+
exports.DEFAULT_RULES_FILE = "firestore.rules";
|
|
12
12
|
const RULES_TEMPLATE = (0, templates_1.readTemplateSync)("init/firestore/firestore.rules");
|
|
13
|
-
|
|
13
|
+
function getDefaultRules() {
|
|
14
|
+
const date = utils.thirtyDaysFromNow();
|
|
15
|
+
const formattedForRules = `${date.getFullYear()}, ${date.getMonth() + 1}, ${date.getDate()}`;
|
|
16
|
+
return RULES_TEMPLATE.replace(/{{IN_30_DAYS}}/g, formattedForRules);
|
|
17
|
+
}
|
|
18
|
+
exports.getDefaultRules = getDefaultRules;
|
|
19
|
+
async function initRules(setup, config, info) {
|
|
14
20
|
logger_1.logger.info();
|
|
15
21
|
logger_1.logger.info("Firestore Security Rules allow you to define how and when to allow");
|
|
16
22
|
logger_1.logger.info("requests. You can keep these rules in your project directory");
|
|
17
23
|
logger_1.logger.info("and publish them with " + clc.bold("firebase deploy") + ".");
|
|
18
24
|
logger_1.logger.info();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (fsutils.fileExistsSync(
|
|
25
|
+
info.rulesFilename =
|
|
26
|
+
info.rulesFilename ||
|
|
27
|
+
(await (0, prompt_1.input)({
|
|
28
|
+
message: "What file should be used for Firestore Rules?",
|
|
29
|
+
default: exports.DEFAULT_RULES_FILE,
|
|
30
|
+
}));
|
|
31
|
+
if (fsutils.fileExistsSync(info.rulesFilename)) {
|
|
26
32
|
const msg = "File " +
|
|
27
|
-
clc.bold(
|
|
33
|
+
clc.bold(info.rulesFilename) +
|
|
28
34
|
" already exists." +
|
|
29
35
|
" Do you want to overwrite it with the Firestore Rules from the Firebase Console?";
|
|
30
36
|
if (!(await (0, prompt_1.confirm)(msg))) {
|
|
37
|
+
info.writeRules = false;
|
|
31
38
|
return;
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
|
-
if (
|
|
35
|
-
|
|
41
|
+
if (setup.projectId) {
|
|
42
|
+
info.rules = await getRulesFromConsole(setup.projectId);
|
|
36
43
|
}
|
|
37
|
-
return getRulesFromConsole(setup.projectId).then((contents) => {
|
|
38
|
-
return config.writeProjectFile(setup.config.firestore.rules, contents);
|
|
39
|
-
});
|
|
40
44
|
}
|
|
41
45
|
exports.initRules = initRules;
|
|
42
|
-
function
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
})
|
|
58
|
-
.then((rules) => {
|
|
59
|
-
if (rules.length <= 0) {
|
|
60
|
-
return utils.reject("Ruleset has no files", { exit: 1 });
|
|
61
|
-
}
|
|
62
|
-
if (rules.length > 1) {
|
|
63
|
-
return utils.reject("Ruleset has too many files: " + rules.length, { exit: 1 });
|
|
64
|
-
}
|
|
65
|
-
return rules[0].content;
|
|
66
|
-
});
|
|
46
|
+
async function getRulesFromConsole(projectId) {
|
|
47
|
+
const name = await gcp.rules.getLatestRulesetName(projectId, "cloud.firestore");
|
|
48
|
+
if (!name) {
|
|
49
|
+
logger_1.logger.debug("No rulesets found, using default.");
|
|
50
|
+
return getDefaultRules();
|
|
51
|
+
}
|
|
52
|
+
logger_1.logger.debug("Found ruleset: " + name);
|
|
53
|
+
const rules = await gcp.rules.getRulesetContent(name);
|
|
54
|
+
if (rules.length <= 0) {
|
|
55
|
+
return utils.reject("Ruleset has no files", { exit: 1 });
|
|
56
|
+
}
|
|
57
|
+
if (rules.length > 1) {
|
|
58
|
+
return utils.reject("Ruleset has too many files: " + rules.length, { exit: 1 });
|
|
59
|
+
}
|
|
60
|
+
return rules[0].content;
|
|
67
61
|
}
|
|
@@ -9,6 +9,7 @@ const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
|
|
|
9
9
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
10
10
|
const error_1 = require("../../../error");
|
|
11
11
|
const api_1 = require("../../../api");
|
|
12
|
+
const supported = require("../../../deploy/functions/runtimes/supported");
|
|
12
13
|
const MAX_ATTEMPTS = 5;
|
|
13
14
|
async function doSetup(setup, config, options) {
|
|
14
15
|
var _a, _b;
|
|
@@ -168,6 +169,7 @@ async function languageSetup(setup, config) {
|
|
|
168
169
|
break;
|
|
169
170
|
case "python":
|
|
170
171
|
cbconfig.ignore = ["venv", ".git", "firebase-debug.log", "firebase-debug.*.log", "*.local"];
|
|
172
|
+
cbconfig.runtime = supported.latest("python");
|
|
171
173
|
break;
|
|
172
174
|
}
|
|
173
175
|
setup.functions.languageChoice = language;
|
|
@@ -5,6 +5,7 @@ const npm_dependencies_1 = require("./npm-dependencies");
|
|
|
5
5
|
const prompt_1 = require("../../../prompt");
|
|
6
6
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
7
7
|
const templates_1 = require("../../../templates");
|
|
8
|
+
const supported = require("../../../deploy/functions/runtimes/supported");
|
|
8
9
|
const INDEX_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/index.js");
|
|
9
10
|
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.lint.json");
|
|
10
11
|
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/javascript/package.nolint.json");
|
|
@@ -17,11 +18,11 @@ async function setup(setup, config) {
|
|
|
17
18
|
if (setup.functions.lint) {
|
|
18
19
|
const cbconfig = (0, projectConfig_1.configForCodebase)(setup.config.functions, setup.functions.codebase);
|
|
19
20
|
cbconfig.predeploy = ['npm --prefix "$RESOURCE_DIR" run lint'];
|
|
20
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE);
|
|
21
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
21
22
|
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
|
|
22
23
|
}
|
|
23
24
|
else {
|
|
24
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE);
|
|
25
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
25
26
|
}
|
|
26
27
|
await config.askWriteProjectFile(`${setup.functions.source}/index.js`, INDEX_TEMPLATE);
|
|
27
28
|
await config.askWriteProjectFile(`${setup.functions.source}/.gitignore`, GITIGNORE_TEMPLATE);
|
|
@@ -5,6 +5,7 @@ const npm_dependencies_1 = require("./npm-dependencies");
|
|
|
5
5
|
const prompt_1 = require("../../../prompt");
|
|
6
6
|
const projectConfig_1 = require("../../../functions/projectConfig");
|
|
7
7
|
const templates_1 = require("../../../templates");
|
|
8
|
+
const supported = require("../../../deploy/functions/runtimes/supported");
|
|
8
9
|
const PACKAGE_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.lint.json");
|
|
9
10
|
const PACKAGE_NO_LINTING_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/package.nolint.json");
|
|
10
11
|
const ESLINT_TEMPLATE = (0, templates_1.readTemplateSync)("init/functions/typescript/_eslintrc");
|
|
@@ -24,13 +25,13 @@ async function setup(setup, config) {
|
|
|
24
25
|
if (setup.functions.lint) {
|
|
25
26
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run lint');
|
|
26
27
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
|
|
27
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE);
|
|
28
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
28
29
|
await config.askWriteProjectFile(`${setup.functions.source}/.eslintrc.js`, ESLINT_TEMPLATE);
|
|
29
30
|
await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.dev.json`, TSCONFIG_DEV_TEMPLATE);
|
|
30
31
|
}
|
|
31
32
|
else {
|
|
32
33
|
cbconfig.predeploy.push('npm --prefix "$RESOURCE_DIR" run build');
|
|
33
|
-
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE);
|
|
34
|
+
await config.askWriteProjectFile(`${setup.functions.source}/package.json`, PACKAGE_NO_LINTING_TEMPLATE.replace("{{RUNTIME}}", supported.latest("nodejs").replace("nodejs", "")));
|
|
34
35
|
}
|
|
35
36
|
await config.askWriteProjectFile(`${setup.functions.source}/tsconfig.json`, TSCONFIG_TEMPLATE);
|
|
36
37
|
await config.askWriteProjectFile(`${setup.functions.source}/src/index.ts`, INDEX_TEMPLATE);
|
|
@@ -89,8 +89,9 @@ function showStartMessage(setup, command) {
|
|
|
89
89
|
logger_1.logger.info("Then start the Genkit developer experience by running:");
|
|
90
90
|
logger_1.logger.info(clc.bold(clc.green(` ${command}`)));
|
|
91
91
|
}
|
|
92
|
-
async function doSetup(
|
|
92
|
+
async function doSetup(initSetup, config, options) {
|
|
93
93
|
var _a;
|
|
94
|
+
const setup = initSetup;
|
|
94
95
|
const genkitInfo = await getGenkitInfo();
|
|
95
96
|
if (genkitInfo.stopInstall) {
|
|
96
97
|
(0, utils_1.logLabeledWarning)("genkit", "Stopped Genkit initialization");
|
|
@@ -67,7 +67,7 @@ async function initGitHub(setup) {
|
|
|
67
67
|
(0, utils_1.logSuccess)(`Uploaded service account JSON to GitHub as secret ${(0, colorette_1.bold)(githubSecretName)}.`);
|
|
68
68
|
(0, utils_1.logBullet)(`You can manage your secrets at https://github.com/${repo}/settings/secrets.`);
|
|
69
69
|
logger_1.logger.info();
|
|
70
|
-
if (setup.config.hosting.predeploy) {
|
|
70
|
+
if (!Array.isArray(setup.config.hosting) && setup.config.hosting.predeploy) {
|
|
71
71
|
(0, utils_1.logBullet)(`You have a predeploy script configured in firebase.json.`);
|
|
72
72
|
}
|
|
73
73
|
const { script } = await promptForBuildScript((_a = setup === null || setup === void 0 ? void 0 : setup.hosting) === null || _a === void 0 ? void 0 : _a.useWebFrameworks);
|
|
@@ -259,7 +259,7 @@ async function uploadSecretToGitHub(repo, ghAccessToken, encryptedServiceAccount
|
|
|
259
259
|
async function promptForRepo(options, ghAccessToken) {
|
|
260
260
|
let key = "";
|
|
261
261
|
let keyId = "";
|
|
262
|
-
const
|
|
262
|
+
const repo = options.repo ||
|
|
263
263
|
(await (0, prompt_1.input)({
|
|
264
264
|
default: defaultGithubRepo(),
|
|
265
265
|
message: "For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository)",
|
|
@@ -287,6 +287,7 @@ async function promptForRepo(options, ghAccessToken) {
|
|
|
287
287
|
return true;
|
|
288
288
|
},
|
|
289
289
|
}));
|
|
290
|
+
options.repo = repo;
|
|
290
291
|
return { repo, key, keyId };
|
|
291
292
|
}
|
|
292
293
|
async function promptForBuildScript(useWebFrameworks) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.genkit = exports.apphosting = exports.dataconnectSdk = exports.
|
|
3
|
+
exports.genkit = exports.apphosting = exports.dataconnectSdk = exports.dataconnectPostSetup = exports.dataconnectActuate = exports.dataconnectAskQuestions = exports.hostingGithub = exports.remoteconfig = exports.project = exports.extensions = exports.emulators = exports.storage = exports.hosting = exports.functions = exports.firestoreActuate = exports.firestoreAskQuestions = exports.databaseActuate = exports.databaseAskQuestions = exports.account = void 0;
|
|
4
4
|
var account_1 = require("./account");
|
|
5
5
|
Object.defineProperty(exports, "account", { enumerable: true, get: function () { return account_1.doSetup; } });
|
|
6
6
|
var database_1 = require("./database");
|
|
7
|
-
Object.defineProperty(exports, "
|
|
7
|
+
Object.defineProperty(exports, "databaseAskQuestions", { enumerable: true, get: function () { return database_1.askQuestions; } });
|
|
8
|
+
Object.defineProperty(exports, "databaseActuate", { enumerable: true, get: function () { return database_1.actuate; } });
|
|
8
9
|
var firestore_1 = require("./firestore");
|
|
9
|
-
Object.defineProperty(exports, "
|
|
10
|
+
Object.defineProperty(exports, "firestoreAskQuestions", { enumerable: true, get: function () { return firestore_1.askQuestions; } });
|
|
11
|
+
Object.defineProperty(exports, "firestoreActuate", { enumerable: true, get: function () { return firestore_1.actuate; } });
|
|
10
12
|
var functions_1 = require("./functions");
|
|
11
13
|
Object.defineProperty(exports, "functions", { enumerable: true, get: function () { return functions_1.doSetup; } });
|
|
12
14
|
var hosting_1 = require("./hosting");
|
|
@@ -24,7 +26,9 @@ Object.defineProperty(exports, "remoteconfig", { enumerable: true, get: function
|
|
|
24
26
|
var github_1 = require("./hosting/github");
|
|
25
27
|
Object.defineProperty(exports, "hostingGithub", { enumerable: true, get: function () { return github_1.initGitHub; } });
|
|
26
28
|
var dataconnect_1 = require("./dataconnect");
|
|
27
|
-
Object.defineProperty(exports, "
|
|
29
|
+
Object.defineProperty(exports, "dataconnectAskQuestions", { enumerable: true, get: function () { return dataconnect_1.askQuestions; } });
|
|
30
|
+
Object.defineProperty(exports, "dataconnectActuate", { enumerable: true, get: function () { return dataconnect_1.actuate; } });
|
|
31
|
+
Object.defineProperty(exports, "dataconnectPostSetup", { enumerable: true, get: function () { return dataconnect_1.postSetup; } });
|
|
28
32
|
var sdk_1 = require("./dataconnect/sdk");
|
|
29
33
|
Object.defineProperty(exports, "dataconnectSdk", { enumerable: true, get: function () { return sdk_1.doSetup; } });
|
|
30
34
|
var apphosting_1 = require("./apphosting");
|
|
@@ -5,7 +5,6 @@ const prompt_1 = require("../../prompt");
|
|
|
5
5
|
const fsutils = require("../../fsutils");
|
|
6
6
|
const clc = require("colorette");
|
|
7
7
|
async function doSetup(setup, config) {
|
|
8
|
-
setup.config.remoteconfig = {};
|
|
9
8
|
const jsonFilePath = await (0, prompt_1.input)({
|
|
10
9
|
message: "What file should be used for your Remote Config template?",
|
|
11
10
|
default: "remoteconfig.template.json",
|
|
@@ -20,7 +19,9 @@ async function doSetup(setup, config) {
|
|
|
20
19
|
return;
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
|
-
setup.config.remoteconfig
|
|
22
|
+
setup.config.remoteconfig = {
|
|
23
|
+
template: jsonFilePath,
|
|
24
|
+
};
|
|
24
25
|
config.writeProjectFile(setup.config.remoteconfig.template, "{}");
|
|
25
26
|
}
|
|
26
27
|
exports.doSetup = doSetup;
|
package/lib/init/index.js
CHANGED
|
@@ -1,45 +1,97 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.init = void 0;
|
|
3
|
+
exports.actuate = exports.init = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
5
|
const clc = require("colorette");
|
|
6
6
|
const error_1 = require("../error");
|
|
7
7
|
const logger_1 = require("../logger");
|
|
8
8
|
const features = require("./features");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
const featuresList = [
|
|
10
|
+
{ name: "account", doSetup: features.account },
|
|
11
|
+
{
|
|
12
|
+
name: "database",
|
|
13
|
+
askQuestions: features.databaseAskQuestions,
|
|
14
|
+
actuate: features.databaseActuate,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "firestore",
|
|
18
|
+
askQuestions: features.firestoreAskQuestions,
|
|
19
|
+
actuate: features.firestoreActuate,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "dataconnect",
|
|
23
|
+
askQuestions: features.dataconnectAskQuestions,
|
|
24
|
+
actuate: features.dataconnectActuate,
|
|
25
|
+
postSetup: features.dataconnectPostSetup,
|
|
26
|
+
},
|
|
27
|
+
{ name: "dataconnect:sdk", doSetup: features.dataconnectSdk },
|
|
28
|
+
{ name: "functions", doSetup: features.functions },
|
|
29
|
+
{ name: "hosting", doSetup: features.hosting },
|
|
30
|
+
{ name: "storage", doSetup: features.storage },
|
|
31
|
+
{ name: "emulators", doSetup: features.emulators },
|
|
32
|
+
{ name: "extensions", doSetup: features.extensions },
|
|
33
|
+
{ name: "project", doSetup: features.project },
|
|
34
|
+
{ name: "remoteconfig", doSetup: features.remoteconfig },
|
|
35
|
+
{ name: "hosting:github", doSetup: features.hostingGithub },
|
|
36
|
+
{ name: "genkit", doSetup: features.genkit },
|
|
37
|
+
{ name: "apphosting", displayName: "App Hosting", doSetup: features.apphosting },
|
|
38
|
+
];
|
|
39
|
+
const featureMap = new Map(featuresList.map((feature) => [feature.name, feature]));
|
|
26
40
|
async function init(setup, config, options) {
|
|
27
41
|
var _a;
|
|
28
42
|
const nextFeature = (_a = setup.features) === null || _a === void 0 ? void 0 : _a.shift();
|
|
29
43
|
if (nextFeature) {
|
|
30
|
-
|
|
44
|
+
const f = featureMap.get(nextFeature);
|
|
45
|
+
if (!f) {
|
|
31
46
|
const availableFeatures = Object.keys(features)
|
|
32
47
|
.filter((f) => f !== "project")
|
|
33
48
|
.join(", ");
|
|
34
49
|
throw new error_1.FirebaseError(`${clc.bold(nextFeature)} is not a valid feature. Must be one of ${availableFeatures}`);
|
|
35
50
|
}
|
|
36
|
-
logger_1.logger.info(clc.bold(`\n${clc.white("===")} ${(0, lodash_1.capitalize)(nextFeature)} Setup`));
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
logger_1.logger.info(clc.bold(`\n${clc.white("===")} ${f.displayName || (0, lodash_1.capitalize)(nextFeature)} Setup`));
|
|
52
|
+
if (f.doSetup) {
|
|
53
|
+
await f.doSetup(setup, config, options);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (f.askQuestions) {
|
|
57
|
+
await f.askQuestions(setup, config, options);
|
|
58
|
+
}
|
|
59
|
+
if (f.actuate) {
|
|
60
|
+
await f.actuate(setup, config, options);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (f.postSetup) {
|
|
64
|
+
await f.postSetup(setup, config, options);
|
|
40
65
|
}
|
|
41
|
-
await fn(setup, config, options);
|
|
42
66
|
return init(setup, config, options);
|
|
43
67
|
}
|
|
44
68
|
}
|
|
45
69
|
exports.init = init;
|
|
70
|
+
async function actuate(setup, config, options) {
|
|
71
|
+
var _a;
|
|
72
|
+
const nextFeature = (_a = setup.features) === null || _a === void 0 ? void 0 : _a.shift();
|
|
73
|
+
if (nextFeature) {
|
|
74
|
+
const f = lookupFeature(nextFeature);
|
|
75
|
+
logger_1.logger.info(clc.bold(`\n${clc.white("===")} ${(0, lodash_1.capitalize)(nextFeature)} Setup Actuation`));
|
|
76
|
+
if (f.doSetup) {
|
|
77
|
+
throw new error_1.FirebaseError(`The feature ${nextFeature} does not support actuate yet. Please run ${clc.bold("firebase init " + nextFeature)} instead.`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
if (f.actuate) {
|
|
81
|
+
await f.actuate(setup, config, options);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return actuate(setup, config, options);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.actuate = actuate;
|
|
88
|
+
function lookupFeature(feature) {
|
|
89
|
+
const f = featureMap.get(feature);
|
|
90
|
+
if (!f) {
|
|
91
|
+
const availableFeatures = Object.keys(features)
|
|
92
|
+
.filter((f) => f !== "project")
|
|
93
|
+
.join(", ");
|
|
94
|
+
throw new error_1.FirebaseError(`${clc.bold(feature)} is not a valid feature. Must be one of ${availableFeatures}`);
|
|
95
|
+
}
|
|
96
|
+
return f;
|
|
97
|
+
}
|