@stoker-platform/cli 0.5.103 → 0.5.105
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/init-files/src/collections/Settings.ts +0 -1
- package/lib/package.json +4 -4
- package/lib/src/deploy/firestore-export/exportFirestoreData.js +3 -0
- package/lib/src/deploy/live-update/liveUpdate.js +2 -3
- package/lib/src/deploy/maintenance/activateMaintenanceMode.js +2 -3
- package/lib/src/deploy/maintenance/disableMaintenanceMode.js +2 -3
- package/lib/src/deploy/maintenance/setDeploymentStatus.js +2 -3
- package/lib/src/deploy/prepareInitialFunctionsDeploy.js +109 -0
- package/lib/src/migration/firestore/operations/deleteField.js +2 -2
- package/lib/src/ops/auditDenormalized.js +2 -3
- package/lib/src/ops/auditPermissions.js +2 -3
- package/lib/src/ops/auditRelations.js +2 -3
- package/lib/src/ops/explainPreloadQueries.js +30 -5
- package/lib/src/ops/getUserPermissions.js +2 -3
- package/lib/src/ops/getUserRecord.js +2 -3
- package/lib/src/project/addProject.js +9 -2
- package/lib/src/project/addTenant.js +2 -3
- package/lib/src/project/deleteTenant.js +2 -3
- package/lib/src/project/prepareEmulatorData.js +2 -0
- package/lib/src/utils/getCliFirestore.js +3 -7
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoker-platform/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"main": "./lib/src/main.js",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"@google-cloud/secret-manager": "^6.1.2",
|
|
25
25
|
"@google-cloud/storage": "^7.19.0",
|
|
26
26
|
"@inquirer/prompts": "^8.5.2",
|
|
27
|
-
"@stoker-platform/node-client": "0.5.
|
|
28
|
-
"@stoker-platform/types": "0.5.
|
|
29
|
-
"@stoker-platform/utils": "0.5.
|
|
27
|
+
"@stoker-platform/node-client": "0.5.69",
|
|
28
|
+
"@stoker-platform/types": "0.5.48",
|
|
29
|
+
"@stoker-platform/utils": "0.5.60",
|
|
30
30
|
"algoliasearch": "^5.53.0",
|
|
31
31
|
"commander": "^15.0.0",
|
|
32
32
|
"cross-spawn": "^7.0.6",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { initializeFirebase, fetchCurrentSchema, runChildProcess } from "@stoker-platform/node-client";
|
|
2
|
+
import { getFirestoreDatabaseId } from "@stoker-platform/utils";
|
|
2
3
|
export const exportFirestoreData = async () => {
|
|
3
4
|
await initializeFirebase();
|
|
4
5
|
const schema = await fetchCurrentSchema();
|
|
@@ -16,6 +17,8 @@ export const exportFirestoreData = async () => {
|
|
|
16
17
|
`gs://${bucket}/`,
|
|
17
18
|
`--collection-ids=${collections.join(",")}`,
|
|
18
19
|
`--project=${process.env.GCP_PROJECT}`,
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
21
|
+
`--database=${getFirestoreDatabaseId(process.env.FB_FIRESTORE_EDITION, process.env.GCP_PROJECT)}`,
|
|
19
22
|
"--quiet",
|
|
20
23
|
]);
|
|
21
24
|
collections = [];
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { fetchCurrentSchema, initializeFirebase } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
2
2
|
import { FieldValue } from "firebase-admin/firestore";
|
|
3
|
-
import { getCLIFirestore } from "../../utils/getCLIFirestore.js";
|
|
4
3
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
4
|
export const liveUpdate = async (options) => {
|
|
6
5
|
await initializeFirebase();
|
|
7
|
-
const db =
|
|
6
|
+
const db = getStokerFirestore();
|
|
8
7
|
const batch = db.batch();
|
|
9
8
|
const currentSchema = await fetchCurrentSchema();
|
|
10
9
|
const deployId = db.collection("system_deployment").doc("latest_deploy").collection("deploy_history").doc().id;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { initializeFirebase } from "@stoker-platform/node-client";
|
|
2
|
-
import { getCLIFirestore } from "../../utils/getCLIFirestore.js";
|
|
1
|
+
import { initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
3
2
|
export const activateMaintenanceMode = async () => {
|
|
4
3
|
await initializeFirebase();
|
|
5
|
-
const db =
|
|
4
|
+
const db = getStokerFirestore();
|
|
6
5
|
await db.collection("system_deployment").doc("maintenance_mode").set({ active: true });
|
|
7
6
|
console.info("MAINTENANCE MODE ENGAGED");
|
|
8
7
|
process.exit();
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { initializeFirebase } from "@stoker-platform/node-client";
|
|
2
|
-
import { getCLIFirestore } from "../../utils/getCLIFirestore.js";
|
|
1
|
+
import { initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
3
2
|
export const disableMaintenanceMode = async () => {
|
|
4
3
|
await initializeFirebase();
|
|
5
|
-
const db =
|
|
4
|
+
const db = getStokerFirestore();
|
|
6
5
|
await db.collection("system_deployment").doc("maintenance_mode").set({ active: false });
|
|
7
6
|
console.info("MAINTENANCE MODE DISENGAGED");
|
|
8
7
|
process.exit();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { initializeFirebase } from "@stoker-platform/node-client";
|
|
2
|
-
import { getCLIFirestore } from "../../utils/getCLIFirestore.js";
|
|
1
|
+
import { initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
3
2
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
export const setDeploymentStatus = async (status) => {
|
|
5
4
|
await initializeFirebase();
|
|
6
|
-
const db =
|
|
5
|
+
const db = getStokerFirestore();
|
|
7
6
|
if (!["idle", "in_progress"].includes(status)) {
|
|
8
7
|
throw new Error("Invalid deployment status");
|
|
9
8
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { runChildProcess } from "@stoker-platform/node-client";
|
|
2
|
+
import { retryOperation } from "@stoker-platform/utils";
|
|
3
|
+
const getProjectNumber = async (projectId) => {
|
|
4
|
+
return runChildProcess("gcloud", [
|
|
5
|
+
"projects",
|
|
6
|
+
"describe",
|
|
7
|
+
projectId,
|
|
8
|
+
"--format=value(projectNumber)",
|
|
9
|
+
"--quiet",
|
|
10
|
+
]);
|
|
11
|
+
};
|
|
12
|
+
const ensureApiEnabled = async (projectId, api) => {
|
|
13
|
+
await runChildProcess("gcloud", ["services", "enable", api, `--project=${projectId}`, "--quiet"]);
|
|
14
|
+
};
|
|
15
|
+
const ensureServiceIdentity = async (projectId, service) => {
|
|
16
|
+
await retryOperation(async () => {
|
|
17
|
+
await runChildProcess("gcloud", [
|
|
18
|
+
"beta",
|
|
19
|
+
"services",
|
|
20
|
+
"identity",
|
|
21
|
+
"create",
|
|
22
|
+
`--service=${service}`,
|
|
23
|
+
`--project=${projectId}`,
|
|
24
|
+
"--quiet",
|
|
25
|
+
]);
|
|
26
|
+
}, [], undefined, 5000, 3);
|
|
27
|
+
};
|
|
28
|
+
const ensureIamBinding = async (projectId, member, role) => {
|
|
29
|
+
await retryOperation(async () => {
|
|
30
|
+
await runChildProcess("gcloud", [
|
|
31
|
+
"projects",
|
|
32
|
+
"add-iam-policy-binding",
|
|
33
|
+
projectId,
|
|
34
|
+
"--member",
|
|
35
|
+
member,
|
|
36
|
+
"--role",
|
|
37
|
+
role,
|
|
38
|
+
"--quiet",
|
|
39
|
+
]);
|
|
40
|
+
}, [], undefined, 5000, 3);
|
|
41
|
+
};
|
|
42
|
+
const ensureGcfArtifactsRepo = async (projectId, region) => {
|
|
43
|
+
await retryOperation(async () => {
|
|
44
|
+
const repositories = await runChildProcess("gcloud", [
|
|
45
|
+
"artifacts",
|
|
46
|
+
"repositories",
|
|
47
|
+
"list",
|
|
48
|
+
`--location=${region}`,
|
|
49
|
+
`--project=${projectId}`,
|
|
50
|
+
"--format=value(name)",
|
|
51
|
+
"--quiet",
|
|
52
|
+
]);
|
|
53
|
+
if (!repositories.includes("gcf-artifacts")) {
|
|
54
|
+
await runChildProcess("gcloud", [
|
|
55
|
+
"artifacts",
|
|
56
|
+
"repositories",
|
|
57
|
+
"create",
|
|
58
|
+
"gcf-artifacts",
|
|
59
|
+
"--repository-format=docker",
|
|
60
|
+
`--location=${region}`,
|
|
61
|
+
`--project=${projectId}`,
|
|
62
|
+
"--quiet",
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
}, [], undefined, 5000);
|
|
66
|
+
};
|
|
67
|
+
const waitForEventarcServiceAgent = async (projectId, projectNumber) => {
|
|
68
|
+
const member = `serviceAccount:service-${projectNumber}@gcp-sa-eventarc.iam.gserviceaccount.com`;
|
|
69
|
+
const maxAttempts = 28;
|
|
70
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
71
|
+
const policy = await runChildProcess("gcloud", [
|
|
72
|
+
"projects",
|
|
73
|
+
"get-iam-policy",
|
|
74
|
+
projectId,
|
|
75
|
+
"--format=json",
|
|
76
|
+
"--quiet",
|
|
77
|
+
]);
|
|
78
|
+
const policyJson = JSON.parse(policy);
|
|
79
|
+
const hasRole = policyJson.bindings?.some((binding) => binding.role === "roles/eventarc.serviceAgent" && binding.members?.includes(member));
|
|
80
|
+
if (hasRole)
|
|
81
|
+
return;
|
|
82
|
+
if (attempt < maxAttempts - 1) {
|
|
83
|
+
await new Promise((resolve) => setTimeout(resolve, 15000));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
throw new Error("Eventarc service agent permissions were not propagated in time.");
|
|
87
|
+
};
|
|
88
|
+
export const isFunctionsDeployRetryable = (output) => output.includes("Eventarc Service Agent") ||
|
|
89
|
+
output.includes("HTTP Error: 400") ||
|
|
90
|
+
output.includes("HTTP Error: 429") ||
|
|
91
|
+
output.includes("failed to create function") ||
|
|
92
|
+
output.includes("2nd gen functions");
|
|
93
|
+
export const prepareInitialFunctionsDeploy = async (projectId, region) => {
|
|
94
|
+
const projectNumber = (await getProjectNumber(projectId)).trim();
|
|
95
|
+
await ensureApiEnabled(projectId, "pubsub.googleapis.com");
|
|
96
|
+
await ensureGcfArtifactsRepo(projectId, region);
|
|
97
|
+
for (const service of [
|
|
98
|
+
"eventarc.googleapis.com",
|
|
99
|
+
"cloudfunctions.googleapis.com",
|
|
100
|
+
"pubsub.googleapis.com",
|
|
101
|
+
"run.googleapis.com",
|
|
102
|
+
]) {
|
|
103
|
+
await ensureServiceIdentity(projectId, service);
|
|
104
|
+
}
|
|
105
|
+
await ensureIamBinding(projectId, `serviceAccount:service-${projectNumber}@gcp-sa-eventarc.iam.gserviceaccount.com`, "roles/eventarc.serviceAgent");
|
|
106
|
+
await ensureIamBinding(projectId, `serviceAccount:${projectNumber}-compute@developer.gserviceaccount.com`, "roles/eventarc.eventReceiver");
|
|
107
|
+
await ensureIamBinding(projectId, `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`, "roles/iam.serviceAccountTokenCreator");
|
|
108
|
+
await waitForEventarcServiceAgent(projectId, projectNumber);
|
|
109
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FieldValue } from "firebase-admin/firestore";
|
|
2
2
|
import { appendFileSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
|
-
import {
|
|
4
|
+
import { getStokerFirestore } from "@stoker-platform/node-client";
|
|
5
5
|
export const deleteField = async (currentSchema, lastSchema) => {
|
|
6
6
|
const deletedFields = [];
|
|
7
7
|
const currentSchemaKeys = Object.keys(currentSchema.collections);
|
|
@@ -20,7 +20,7 @@ export const deleteField = async (currentSchema, lastSchema) => {
|
|
|
20
20
|
});
|
|
21
21
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
22
22
|
const filePath = join(process.cwd(), ".migration", process.env.GCP_PROJECT, `v${currentSchema.version.toString()}`);
|
|
23
|
-
const db =
|
|
23
|
+
const db = getStokerFirestore();
|
|
24
24
|
const bulkWriter = db.bulkWriter();
|
|
25
25
|
for (const field of deletedFields) {
|
|
26
26
|
const [collection, fieldName] = field.split(".");
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { fetchCurrentSchema, initializeStoker } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, initializeStoker, getStokerFirestore } from "@stoker-platform/node-client";
|
|
2
2
|
import { getDependencyIndexFields, getLowercaseFields, getRoleGroups, getSingleFieldRelations, isDependencyField, isRelationField, } from "@stoker-platform/utils";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
5
4
|
import isEqual from "lodash/isEqual.js";
|
|
6
5
|
import isEmpty from "lodash/isEmpty.js";
|
|
7
6
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
7
|
export const auditDenormalized = async (options) => {
|
|
9
8
|
await initializeStoker(options.mode || "production", options.tenant, join(process.cwd(), "lib", "main.js"), join(process.cwd(), "lib", "collections"));
|
|
10
9
|
const schema = await fetchCurrentSchema();
|
|
11
|
-
const db =
|
|
10
|
+
const db = getStokerFirestore();
|
|
12
11
|
for (const [collectionName, collectionSchema] of Object.entries(schema.collections)) {
|
|
13
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
13
|
const collectionData = {};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { fetchCurrentSchema, initializeStoker } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, initializeStoker, getStokerFirestore } from "@stoker-platform/node-client";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
4
3
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
4
|
export const auditPermissions = async (options) => {
|
|
6
5
|
await initializeStoker(options.mode || "production", options.tenant, join(process.cwd(), "lib", "main.js"), join(process.cwd(), "lib", "collections"));
|
|
7
6
|
const schema = await fetchCurrentSchema();
|
|
8
|
-
const db =
|
|
7
|
+
const db = getStokerFirestore();
|
|
9
8
|
const mismatches = [];
|
|
10
9
|
const permissions = await db.collection("tenants").doc(options.tenant).collection("system_user_permissions").get();
|
|
11
10
|
for (const authCollection of Object.values(schema.collections)) {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { fetchCurrentSchema, getFirestorePathRef, initializeStoker } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, getFirestorePathRef, initializeStoker, getStokerFirestore, } from "@stoker-platform/node-client";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
4
3
|
import isEqual from "lodash/isEqual.js";
|
|
5
4
|
import { getField, getLowercaseFields, getSingleFieldRelations } from "@stoker-platform/utils";
|
|
6
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
6
|
export const auditRelations = async (options) => {
|
|
8
7
|
await initializeStoker(options.mode || "production", options.tenant, join(process.cwd(), "lib", "main.js"), join(process.cwd(), "lib", "collections"));
|
|
9
8
|
const schema = await fetchCurrentSchema();
|
|
10
|
-
const db =
|
|
9
|
+
const db = getStokerFirestore();
|
|
11
10
|
const tenantPrefix = `tenants/${options.tenant}`;
|
|
12
11
|
const recordByDocumentPath = new Map();
|
|
13
12
|
const collectionDocsByName = new Map();
|
|
@@ -1,14 +1,39 @@
|
|
|
1
|
-
import { fetchCurrentSchema, getCollectionRefs, initializeStoker } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, getCollectionRefs, initializeStoker, getStokerFirestore, } from "@stoker-platform/node-client";
|
|
2
2
|
import { tryPromise, getRange } from "@stoker-platform/utils";
|
|
3
3
|
import { Filter } from "firebase-admin/firestore";
|
|
4
4
|
import { join } from "path";
|
|
5
|
-
|
|
5
|
+
const explainQuery = async (_db, query, analyze) => {
|
|
6
|
+
const edition = process.env.FB_FIRESTORE_EDITION || "enterprise";
|
|
7
|
+
if (edition === "enterprise") {
|
|
8
|
+
/*
|
|
9
|
+
const pipeline = db.pipeline().createFrom(query)
|
|
10
|
+
const snapshot = analyze
|
|
11
|
+
? await pipeline.execute({
|
|
12
|
+
explainOptions: { mode: "analyze", outputFormat: "text" },
|
|
13
|
+
})
|
|
14
|
+
: await pipeline.execute({
|
|
15
|
+
rawOptions: {
|
|
16
|
+
"explain_options.mode": "explain",
|
|
17
|
+
"explain_options.output_format": "text",
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
const stats = snapshot.explainStats
|
|
21
|
+
if (!stats) {
|
|
22
|
+
throw new Error("No explain results")
|
|
23
|
+
}
|
|
24
|
+
return stats.text
|
|
25
|
+
*/
|
|
26
|
+
return "Explain is temporarily disabled for enterprise edition.";
|
|
27
|
+
}
|
|
28
|
+
const results = await query.explain({ analyze });
|
|
29
|
+
return results.metrics;
|
|
30
|
+
};
|
|
6
31
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
32
|
export const explainPreloadQueries = async (options) => {
|
|
8
33
|
const { getGlobalConfigModule } = await initializeStoker("production", options.tenant, join(process.cwd(), "lib", "main.js"), join(process.cwd(), "lib", "collections"));
|
|
9
34
|
const globalConfig = getGlobalConfigModule();
|
|
10
35
|
const schema = await fetchCurrentSchema();
|
|
11
|
-
const db =
|
|
36
|
+
const db = getStokerFirestore();
|
|
12
37
|
const permissionsSnapshot = await db
|
|
13
38
|
.collection("tenants")
|
|
14
39
|
.doc(options.tenant)
|
|
@@ -57,8 +82,8 @@ export const explainPreloadQueries = async (options) => {
|
|
|
57
82
|
});
|
|
58
83
|
console.log(`${collection}:`);
|
|
59
84
|
for (const query of queries) {
|
|
60
|
-
const metrics = await
|
|
61
|
-
console.log(JSON.stringify(metrics
|
|
85
|
+
const metrics = await explainQuery(db, query, options.analyze);
|
|
86
|
+
console.log(typeof metrics === "string" ? metrics : JSON.stringify(metrics));
|
|
62
87
|
}
|
|
63
88
|
console.log("\n");
|
|
64
89
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { initializeFirebase } from "@stoker-platform/node-client";
|
|
2
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
1
|
+
import { initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
3
2
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
export const getUserPermissions = async (options) => {
|
|
5
4
|
await initializeFirebase();
|
|
6
|
-
const db =
|
|
5
|
+
const db = getStokerFirestore();
|
|
7
6
|
const usersRef = await db
|
|
8
7
|
.collection("tenants")
|
|
9
8
|
.doc(options.tenant)
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { initializeFirebase } from "@stoker-platform/node-client";
|
|
2
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
1
|
+
import { initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
3
2
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
3
|
export const getUserRecord = async (options) => {
|
|
5
4
|
await initializeFirebase();
|
|
6
|
-
const db =
|
|
5
|
+
const db = getStokerFirestore();
|
|
7
6
|
const usersRef = await db
|
|
8
7
|
.collection("tenants")
|
|
9
8
|
.doc(options.tenant)
|
|
@@ -438,9 +438,9 @@ export const addProject = async (options) => {
|
|
|
438
438
|
await runChildProcess("attrib", ["-H", firebasercPath]);
|
|
439
439
|
}
|
|
440
440
|
await runChildProcess("firebase", ["target:apply", "storage", "default", projectId, "--project", projectId]);
|
|
441
|
+
const firebaseJsonPath = join(process.cwd(), "firebase.json");
|
|
442
|
+
const firebaseJson = JSON.parse(await readFile(firebaseJsonPath, "utf8"));
|
|
441
443
|
if ((process.env.FB_FIRESTORE_EDITION || "enterprise") === "enterprise") {
|
|
442
|
-
const firebaseJsonPath = join(process.cwd(), "firebase.json");
|
|
443
|
-
const firebaseJson = JSON.parse(await readFile(firebaseJsonPath, "utf8"));
|
|
444
444
|
firebaseJson.firestore = [
|
|
445
445
|
{
|
|
446
446
|
database: projectId,
|
|
@@ -450,6 +450,13 @@ export const addProject = async (options) => {
|
|
|
450
450
|
];
|
|
451
451
|
await writeFile(firebaseJsonPath, JSON.stringify(firebaseJson, null, 4), "utf8");
|
|
452
452
|
}
|
|
453
|
+
else {
|
|
454
|
+
firebaseJson.firestore = {
|
|
455
|
+
rules: "firebase-rules/firestore.rules",
|
|
456
|
+
indexes: "firebase-rules/firestore.indexes.json",
|
|
457
|
+
};
|
|
458
|
+
await writeFile(firebaseJsonPath, JSON.stringify(firebaseJson, null, 4), "utf8");
|
|
459
|
+
}
|
|
453
460
|
await updateProjectData(17);
|
|
454
461
|
}
|
|
455
462
|
if (getProgress() < 18) {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { input } from "@inquirer/prompts";
|
|
2
|
-
import { fetchCurrentSchema, initializeFirebase, initializeStoker } from "@stoker-platform/node-client";
|
|
2
|
+
import { fetchCurrentSchema, initializeFirebase, initializeStoker, getStokerFirestore, } from "@stoker-platform/node-client";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { retryOperation, isRelationField } from "@stoker-platform/utils";
|
|
5
5
|
import { addRecordPrompt } from "./addRecordPrompt.js";
|
|
6
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
7
6
|
export const addTenant = async () => {
|
|
8
7
|
await initializeFirebase();
|
|
9
|
-
const db =
|
|
8
|
+
const db = getStokerFirestore();
|
|
10
9
|
const doc = await db.collection("tenants").add({});
|
|
11
10
|
const tenantId = doc.id;
|
|
12
11
|
await initializeStoker("production", tenantId, join(process.cwd(), "lib", "main.js"), join(process.cwd(), "lib", "collections"));
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { fetchCurrentSchema, initializeFirebase } from "@stoker-platform/node-client";
|
|
1
|
+
import { fetchCurrentSchema, initializeFirebase, getStokerFirestore } from "@stoker-platform/node-client";
|
|
2
2
|
import { getAuth } from "firebase-admin/auth";
|
|
3
3
|
import { getApp } from "firebase-admin/app";
|
|
4
4
|
import { getStorage } from "firebase-admin/storage";
|
|
5
|
-
import { getCLIFirestore } from "../utils/getCLIFirestore.js";
|
|
6
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
6
|
export const deleteTenant = async (options) => {
|
|
8
7
|
await initializeFirebase();
|
|
9
8
|
const app = getApp();
|
|
10
9
|
const auth = getAuth();
|
|
11
|
-
const db =
|
|
10
|
+
const db = getStokerFirestore();
|
|
12
11
|
const storage = getStorage();
|
|
13
12
|
const schema = await fetchCurrentSchema();
|
|
14
13
|
const users = await db.collection("tenants").doc(options.tenant).collection("system_user_permissions").get();
|
|
@@ -2,6 +2,7 @@ import { initializeFirebase, runChildProcess } from "@stoker-platform/node-clien
|
|
|
2
2
|
import { getDatabase } from "firebase-admin/database";
|
|
3
3
|
import { mkdir, rm, writeFile } from "fs/promises";
|
|
4
4
|
import { join } from "path";
|
|
5
|
+
import { getFirestoreDatabaseId } from "@stoker-platform/utils";
|
|
5
6
|
export const prepareEmulatorData = async () => {
|
|
6
7
|
if (!process.env.GCP_PROJECT) {
|
|
7
8
|
throw new Error("GCP_PROJECT not set.");
|
|
@@ -94,6 +95,7 @@ export const prepareEmulatorData = async () => {
|
|
|
94
95
|
"firestore",
|
|
95
96
|
"export",
|
|
96
97
|
`gs://${process.env.GCP_PROJECT}/firestore_export`,
|
|
98
|
+
`--database=${getFirestoreDatabaseId(process.env.FB_FIRESTORE_EDITION, process.env.GCP_PROJECT)}`,
|
|
97
99
|
"--project",
|
|
98
100
|
process.env.GCP_PROJECT,
|
|
99
101
|
]);
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const getCLIFirestore = (app) => {
|
|
5
|
-
return getFirestore(app || getApp(),
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
7
|
-
getFirestoreDatabaseId(process.env.FB_FIRESTORE_EDITION, process.env.GCP_PROJECT));
|
|
1
|
+
import { getStokerFirestore } from "@stoker-platform/node-client";
|
|
2
|
+
export const getCLIFirestore = () => {
|
|
3
|
+
return getStokerFirestore();
|
|
8
4
|
};
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/main.ts","../src/data/exporttobigquery.ts","../src/data/seeddata.ts","../src/deploy/deployproject.ts","../src/deploy/cloud-functions/getfunctionsdata.ts","../src/deploy/firestore-export/exportfirestoredata.ts","../src/deploy/firestore-ttl/deployttls.ts","../src/deploy/live-update/liveupdate.ts","../src/deploy/maintenance/activatemaintenancemode.ts","../src/deploy/maintenance/disablemaintenancemode.ts","../src/deploy/maintenance/setdeploymentstatus.ts","../src/deploy/rules-indexes/generatefirestoreindexes.ts","../src/deploy/rules-indexes/generatefirestorerules.ts","../src/deploy/rules-indexes/generatestoragerules.ts","../src/deploy/schema/applyschema.ts","../src/deploy/schema/generateschema.ts","../src/deploy/schema/persistschema.ts","../src/deploy/schema/updateliveschema.ts","../src/lint/lintschema.ts","../src/lint/securityreport.ts","../src/migration/migrateall.ts","../src/migration/firestore/migratefirestore.ts","../src/migration/firestore/operations/deletefield.ts","../src/ops/auditdenormalized.ts","../src/ops/auditpermissions.ts","../src/ops/auditrelations.ts","../src/ops/explainpreloadqueries.ts","../src/ops/getuser.ts","../src/ops/getuserpermissions.ts","../src/ops/getuserrecord.ts","../src/ops/listprojects.ts","../src/ops/setusercollection.ts","../src/ops/setuserdocument.ts","../src/ops/setuserrole.ts","../src/project/addproject.ts","../src/project/addrecord.ts","../src/project/addrecordprompt.ts","../src/project/addtenant.ts","../src/project/buildwebapp.ts","../src/project/customdomain.ts","../src/project/deleteproject.ts","../src/project/deleterecord.ts","../src/project/deletetenant.ts","../src/project/getone.ts","../src/project/getsome.ts","../src/project/initproject.ts","../src/project/prepareemulatordata.ts","../src/project/setproject.ts","../src/project/startemulators.ts","../src/project/updaterecord.ts","../src/types/generatetypes.ts"
|
|
1
|
+
{"root":["../src/main.ts","../src/data/exporttobigquery.ts","../src/data/seeddata.ts","../src/deploy/deployproject.ts","../src/deploy/cloud-functions/getfunctionsdata.ts","../src/deploy/firestore-export/exportfirestoredata.ts","../src/deploy/firestore-ttl/deployttls.ts","../src/deploy/live-update/liveupdate.ts","../src/deploy/maintenance/activatemaintenancemode.ts","../src/deploy/maintenance/disablemaintenancemode.ts","../src/deploy/maintenance/setdeploymentstatus.ts","../src/deploy/rules-indexes/generatefirestoreindexes.ts","../src/deploy/rules-indexes/generatefirestorerules.ts","../src/deploy/rules-indexes/generatestoragerules.ts","../src/deploy/schema/applyschema.ts","../src/deploy/schema/generateschema.ts","../src/deploy/schema/persistschema.ts","../src/deploy/schema/updateliveschema.ts","../src/lint/lintschema.ts","../src/lint/securityreport.ts","../src/migration/migrateall.ts","../src/migration/firestore/migratefirestore.ts","../src/migration/firestore/operations/deletefield.ts","../src/ops/auditdenormalized.ts","../src/ops/auditpermissions.ts","../src/ops/auditrelations.ts","../src/ops/explainpreloadqueries.ts","../src/ops/getuser.ts","../src/ops/getuserpermissions.ts","../src/ops/getuserrecord.ts","../src/ops/listprojects.ts","../src/ops/setusercollection.ts","../src/ops/setuserdocument.ts","../src/ops/setuserrole.ts","../src/project/addproject.ts","../src/project/addrecord.ts","../src/project/addrecordprompt.ts","../src/project/addtenant.ts","../src/project/buildwebapp.ts","../src/project/customdomain.ts","../src/project/deleteproject.ts","../src/project/deleterecord.ts","../src/project/deletetenant.ts","../src/project/getone.ts","../src/project/getsome.ts","../src/project/initproject.ts","../src/project/prepareemulatordata.ts","../src/project/setproject.ts","../src/project/startemulators.ts","../src/project/updaterecord.ts","../src/types/generatetypes.ts"],"version":"6.0.3"}
|