emberflow 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/index-utils.d.ts +4 -0
- package/lib/index-utils.js +96 -21
- package/lib/index-utils.js.map +1 -1
- package/lib/index.d.ts +9 -3
- package/lib/index.js +42 -18
- package/lib/index.js.map +1 -1
- package/lib/tests/index-utils.test.js +14 -46
- package/lib/tests/index-utils.test.js.map +1 -1
- package/lib/tests/index.test.js +63 -31
- package/lib/tests/index.test.js.map +1 -1
- package/lib/tests/utils/batch.test.d.ts +1 -0
- package/lib/tests/utils/batch.test.js +128 -0
- package/lib/tests/utils/batch.test.js.map +1 -0
- package/lib/tests/utils/bill-protect.test.d.ts +1 -0
- package/lib/tests/utils/bill-protect.test.js +241 -0
- package/lib/tests/utils/bill-protect.test.js.map +1 -0
- package/lib/tests/utils/misc.test.js +24 -0
- package/lib/tests/utils/misc.test.js.map +1 -1
- package/lib/tests/utils/paths.test.js +21 -29
- package/lib/tests/utils/paths.test.js.map +1 -1
- package/lib/tests/utils/query.test.js +6 -8
- package/lib/tests/utils/query.test.js.map +1 -1
- package/lib/types.d.ts +15 -0
- package/lib/utils/batch.d.ts +9 -0
- package/lib/utils/batch.js +35 -0
- package/lib/utils/batch.js.map +1 -0
- package/lib/utils/bill-protect.d.ts +72 -0
- package/lib/utils/bill-protect.js +227 -0
- package/lib/utils/bill-protect.js.map +1 -0
- package/lib/utils/misc.d.ts +1 -0
- package/lib/utils/misc.js +13 -1
- package/lib/utils/misc.js.map +1 -1
- package/lib/utils/paths.d.ts +4 -1
- package/lib/utils/paths.js +19 -17
- package/lib/utils/paths.js.map +1 -1
- package/lib/utils/query.js +1 -1
- package/lib/utils/query.js.map +1 -1
- package/package.json +6 -2
- package/src/sample-custom/firestore.rules +16 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.resetUsageStats = exports.stopBillingIfBudgetExceeded = exports.useBillProtect = exports._mockable = exports.computeElapseTime = exports.computeTotalCost = exports.billing = void 0;
|
|
27
|
+
const index_1 = require("../index");
|
|
28
|
+
const billing_1 = require("@google-cloud/billing");
|
|
29
|
+
const firebase_admin_1 = require("firebase-admin");
|
|
30
|
+
const batch = __importStar(require("../utils/batch"));
|
|
31
|
+
exports.billing = new billing_1.CloudBillingClient();
|
|
32
|
+
async function fetchAndInitFuncConfig(db, funcName) {
|
|
33
|
+
const funcConfigRef = db.collection("@server").doc("config")
|
|
34
|
+
.collection("functions").doc(funcName);
|
|
35
|
+
const funcConfig = await funcConfigRef.get();
|
|
36
|
+
let funcConfigData;
|
|
37
|
+
const { maxCostLimitPerFunction, specialCostLimitPerFunction } = index_1.projectConfig;
|
|
38
|
+
if (!funcConfig.exists) {
|
|
39
|
+
funcConfigData = {
|
|
40
|
+
vCPU: 0.167,
|
|
41
|
+
mem: 256,
|
|
42
|
+
costLimit: specialCostLimitPerFunction[funcName] || maxCostLimitPerFunction,
|
|
43
|
+
pricePer100ms: 0.000000648,
|
|
44
|
+
pricePer1MInvocation: 0.40,
|
|
45
|
+
enabled: true,
|
|
46
|
+
};
|
|
47
|
+
await funcConfigRef.set(funcConfigData);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
funcConfigData = funcConfig.data();
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
funcConfigRef,
|
|
54
|
+
funcConfig: funcConfigData,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function fetchAndInitFuncUsage(db, funcName) {
|
|
58
|
+
const funcUsageRef = db.collection("@server").doc("usage")
|
|
59
|
+
.collection("functions").doc(funcName);
|
|
60
|
+
const funcUsage = await funcUsageRef.get();
|
|
61
|
+
let funcUsageData;
|
|
62
|
+
if (!funcUsage.exists) {
|
|
63
|
+
funcUsageData = { totalElapsedTimeInMs: 0, totalInvocations: 0 };
|
|
64
|
+
await funcUsageRef.set(funcUsageData);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
funcUsageData = funcUsage.data();
|
|
68
|
+
}
|
|
69
|
+
return { funcUsageRef, funcUsage: funcUsageData };
|
|
70
|
+
}
|
|
71
|
+
function computeTotalCost(totalInvocations, pricePer1MInvocation, totalElapsedTimeInMs, pricePer100ms) {
|
|
72
|
+
const invocationCost = Math.max(0, (totalInvocations - 2000000)) * pricePer1MInvocation / 1000000;
|
|
73
|
+
const computeTimeCost = totalElapsedTimeInMs * pricePer100ms / 100;
|
|
74
|
+
return invocationCost + computeTimeCost;
|
|
75
|
+
}
|
|
76
|
+
exports.computeTotalCost = computeTotalCost;
|
|
77
|
+
async function lockdownCollection(entity) {
|
|
78
|
+
const app = index_1.admin.app();
|
|
79
|
+
// Get the current Firestore rules.
|
|
80
|
+
const ruleset = await app.securityRules().getFirestoreRuleset();
|
|
81
|
+
let currentRules = ruleset.source[0].content;
|
|
82
|
+
// Define the new match block.
|
|
83
|
+
const docPath = index_1.docPaths[entity];
|
|
84
|
+
const newMatchBlock = `
|
|
85
|
+
match /databases/{database}/${docPath} {
|
|
86
|
+
allow write: if false;
|
|
87
|
+
}`;
|
|
88
|
+
// Insert the new match block before the last closing brace of the `match /databases/{database}/documents` block.
|
|
89
|
+
const insertionIndex = currentRules.lastIndexOf("}");
|
|
90
|
+
currentRules = currentRules.substring(0, insertionIndex) + newMatchBlock + currentRules.substring(insertionIndex);
|
|
91
|
+
// Update the Firestore rules with the new rules.
|
|
92
|
+
await app.securityRules().releaseFirestoreRulesetFromSource(currentRules);
|
|
93
|
+
}
|
|
94
|
+
function computeElapseTime(startTime, endTime) {
|
|
95
|
+
const startTimeInMs = (startTime[0] * 1e9 + startTime[1]) / 1e6; // Convert to milliseconds
|
|
96
|
+
const endTimeInMs = (endTime[0] * 1e9 + endTime[1]) / 1e6; // Convert to milliseconds
|
|
97
|
+
// Round up to nearest 100ms increment
|
|
98
|
+
return Math.ceil((endTimeInMs - startTimeInMs) / 100) * 100;
|
|
99
|
+
}
|
|
100
|
+
exports.computeElapseTime = computeElapseTime;
|
|
101
|
+
async function incrementTotalInvocations(funcUsageRef) {
|
|
102
|
+
await funcUsageRef.update({
|
|
103
|
+
totalInvocations: index_1.admin.firestore.FieldValue.increment(1),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async function incrementTotalElapsedTimeInMs(funcUsageRef, totalElapsedTimeInMs) {
|
|
107
|
+
await funcUsageRef.update({
|
|
108
|
+
totalElapsedTimeInMs: index_1.admin.firestore.FieldValue.increment(totalElapsedTimeInMs),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async function disableFunc(funcConfigRef) {
|
|
112
|
+
await funcConfigRef.update({ enabled: false });
|
|
113
|
+
}
|
|
114
|
+
let hardDisabled = false;
|
|
115
|
+
function isHardDisabled() {
|
|
116
|
+
return hardDisabled;
|
|
117
|
+
}
|
|
118
|
+
exports._mockable = {
|
|
119
|
+
fetchAndInitFuncConfig,
|
|
120
|
+
fetchAndInitFuncUsage,
|
|
121
|
+
computeTotalCost,
|
|
122
|
+
lockdownCollection,
|
|
123
|
+
computeElapseTime,
|
|
124
|
+
incrementTotalInvocations,
|
|
125
|
+
incrementTotalElapsedTimeInMs,
|
|
126
|
+
disableFunc,
|
|
127
|
+
isHardDisabled,
|
|
128
|
+
isBillingEnabled,
|
|
129
|
+
disableBillingForProject,
|
|
130
|
+
};
|
|
131
|
+
function useBillProtect(onDocChange) {
|
|
132
|
+
return async (funcName, entity, change, context, event) => {
|
|
133
|
+
if (exports._mockable.isHardDisabled()) {
|
|
134
|
+
console.warn(`Function ${funcName} is hard disabled. Returning immediately`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const startTime = process.hrtime();
|
|
138
|
+
const { funcUsageRef, funcUsage: { totalElapsedTimeInMs, totalInvocations } } = await exports._mockable.fetchAndInitFuncUsage(index_1.db, funcName);
|
|
139
|
+
try {
|
|
140
|
+
const { funcConfigRef, funcConfig: { costLimit, pricePer100ms, pricePer1MInvocation, enabled, } } = await exports._mockable.fetchAndInitFuncConfig(index_1.db, funcName);
|
|
141
|
+
await exports._mockable.incrementTotalInvocations(funcUsageRef);
|
|
142
|
+
if (!enabled) {
|
|
143
|
+
console.warn(`Function ${funcName} is disabled. Returning`);
|
|
144
|
+
hardDisabled = true;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const totalCost = exports._mockable.computeTotalCost(totalInvocations + 1, pricePer1MInvocation, totalElapsedTimeInMs, pricePer100ms);
|
|
148
|
+
if (totalCost >= costLimit) {
|
|
149
|
+
console.warn(`Function ${funcName} has exceeded the cost limit of $${costLimit}`);
|
|
150
|
+
await exports._mockable.disableFunc(funcConfigRef);
|
|
151
|
+
// Update firestore rules to lockdown collection
|
|
152
|
+
await exports._mockable.lockdownCollection(entity);
|
|
153
|
+
// TODO: Send email to all devs
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
return onDocChange(funcName, entity, change, context, event);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
const endTime = process.hrtime();
|
|
160
|
+
await exports._mockable.incrementTotalElapsedTimeInMs(funcUsageRef, exports._mockable.computeElapseTime(startTime, endTime));
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
exports.useBillProtect = useBillProtect;
|
|
165
|
+
async function stopBillingIfBudgetExceeded(pubSubEvent) {
|
|
166
|
+
const PROJECT_ID = index_1.projectConfig.projectId;
|
|
167
|
+
const PROJECT_NAME = `projects/${PROJECT_ID}`;
|
|
168
|
+
const pubsubData = JSON.parse(Buffer.from(pubSubEvent.data, "base64").toString());
|
|
169
|
+
if (pubsubData.costAmount <= pubsubData.budgetAmount) {
|
|
170
|
+
console.log(`No action necessary. (Current cost: ${pubsubData.costAmount})`);
|
|
171
|
+
return `No action necessary. (Current cost: ${pubsubData.costAmount})`;
|
|
172
|
+
}
|
|
173
|
+
const billingEnabled = await exports._mockable.isBillingEnabled(PROJECT_NAME);
|
|
174
|
+
if (billingEnabled) {
|
|
175
|
+
console.log("Disabling billing");
|
|
176
|
+
return exports._mockable.disableBillingForProject(PROJECT_NAME);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
console.log("Billing already disabled");
|
|
180
|
+
return "Billing already disabled";
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.stopBillingIfBudgetExceeded = stopBillingIfBudgetExceeded;
|
|
184
|
+
/**
|
|
185
|
+
* Determine whether billing is enabled for a project
|
|
186
|
+
* @param {string} projectName Name of project to check if billing is enabled
|
|
187
|
+
* @return {Promise<boolean>} Whether project has billing enabled or not
|
|
188
|
+
*/
|
|
189
|
+
async function isBillingEnabled(projectName) {
|
|
190
|
+
try {
|
|
191
|
+
const [res] = await exports.billing.getProjectBillingInfo({ name: projectName });
|
|
192
|
+
return res.billingEnabled || true;
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
console.log("Unable to determine if billing is enabled on specified project, assuming billing is enabled");
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Disable billing for a project by removing its billing account
|
|
201
|
+
* @param {string} projectName Name of project to disable billing on
|
|
202
|
+
* @return {Promise<string>} Text containing response from disabling billing
|
|
203
|
+
*/
|
|
204
|
+
async function disableBillingForProject(projectName) {
|
|
205
|
+
const [res] = await exports.billing.updateProjectBillingInfo({
|
|
206
|
+
name: projectName,
|
|
207
|
+
projectBillingInfo: {
|
|
208
|
+
billingAccountName: "",
|
|
209
|
+
}, // Disable billing
|
|
210
|
+
});
|
|
211
|
+
console.log(`Billing disabled: ${JSON.stringify(res)}`);
|
|
212
|
+
return `Billing disabled: ${JSON.stringify(res)}`;
|
|
213
|
+
}
|
|
214
|
+
async function resetUsageStats() {
|
|
215
|
+
const usageCollectionPath = "@server/usage/functions";
|
|
216
|
+
const collectionRef = index_1.db.collection(usageCollectionPath);
|
|
217
|
+
const querySnapshot = await collectionRef.select(firebase_admin_1.firestore.FieldPath.documentId()).get();
|
|
218
|
+
querySnapshot.forEach((doc) => {
|
|
219
|
+
return batch.set(doc.ref, {
|
|
220
|
+
totalElapsedTimeInMs: 0,
|
|
221
|
+
totalInvocations: 0,
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
await batch.commit();
|
|
225
|
+
}
|
|
226
|
+
exports.resetUsageStats = resetUsageStats;
|
|
227
|
+
//# sourceMappingURL=bill-protect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bill-protect.js","sourceRoot":"","sources":["../../src/utils/bill-protect.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/misc.d.ts
CHANGED
package/lib/utils/misc.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deepEqual = void 0;
|
|
3
|
+
exports.computeHashCode = exports.deepEqual = void 0;
|
|
4
4
|
const firebase_admin_1 = require("firebase-admin");
|
|
5
5
|
var Timestamp = firebase_admin_1.firestore.Timestamp;
|
|
6
6
|
var GeoPoint = firebase_admin_1.firestore.GeoPoint;
|
|
@@ -50,4 +50,16 @@ function deepEqual(a, b) {
|
|
|
50
50
|
return false;
|
|
51
51
|
}
|
|
52
52
|
exports.deepEqual = deepEqual;
|
|
53
|
+
function computeHashCode(str) {
|
|
54
|
+
let hashCode = 0;
|
|
55
|
+
if (str.length === 0) {
|
|
56
|
+
return hashCode.toString(16).padStart(8, "0"); // Pad with leading zeros to achieve 20 characters
|
|
57
|
+
}
|
|
58
|
+
for (let i = 0; i < str.length; i++) {
|
|
59
|
+
const char = str.charCodeAt(i);
|
|
60
|
+
hashCode = ((hashCode << 5) - hashCode + char) >>> 0; // Convert to unsigned 32-bit integer
|
|
61
|
+
}
|
|
62
|
+
return hashCode.toString(16).padStart(8, "0"); // Pad with leading zeros to achieve 20 characters and truncate to first 20 characters
|
|
63
|
+
}
|
|
64
|
+
exports.computeHashCode = computeHashCode;
|
|
53
65
|
//# sourceMappingURL=misc.js.map
|
package/lib/utils/misc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/utils/misc.ts"],"names":[],"mappings":";;;AAAA,mDAAyC;AACzC,IAAO,SAAS,GAAG,0BAAS,CAAC,SAAS,CAAC;AACvC,IAAO,QAAQ,GAAG,0BAAS,CAAC,QAAQ,CAAC;AAErC,SAAS,QAAQ,CAAC,IAAS;IACzB,OAAO,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,OAAO,CAAC,IAAS;IACxB,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAS;IACrC,OAAO,IAAI,YAAY,SAAS,CAAC;AACnC,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAS;IACpC,OAAO,IAAI,YAAY,QAAQ,CAAC;AAClC,CAAC;AAED,SAAgB,SAAS,CAAC,CAAM,EAAE,CAAM;IACtC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzB,IAAI,oBAAoB,CAAC,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,EAAE;QACtD,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KACrB;IAED,IAAI,mBAAmB,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,EAAE;QACpD,OAAO,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,CAAC;KACjE;IAED,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE;QAC5B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;SAC1C;QACD,OAAO,IAAI,CAAC;KACb;IAED,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAEhD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE;YACvB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;SAC9C;QAED,OAAO,IAAI,CAAC;KACb;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAlCD,8BAkCC"}
|
|
1
|
+
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/utils/misc.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/paths.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QueryCondition } from "../types";
|
|
2
2
|
export declare const _mockable: {
|
|
3
|
-
filterSubDocPathsByEntity:
|
|
3
|
+
filterSubDocPathsByEntity: typeof filterSubDocPathsByEntity;
|
|
4
|
+
doesPathExists: typeof doesPathExists;
|
|
4
5
|
};
|
|
5
6
|
export declare function findMatchingDocPathRegex(docPath: string): {
|
|
6
7
|
entity: string;
|
|
@@ -13,4 +14,6 @@ export declare function filterSubDocPathsByEntity(entity: string, excludeEntitie
|
|
|
13
14
|
export declare function expandAndGroupDocPaths(startingDocPath: string, entityCondition?: Record<string, QueryCondition>, excludeEntities?: string[]): Promise<{
|
|
14
15
|
[key: string]: string[];
|
|
15
16
|
}>;
|
|
17
|
+
declare function doesPathExists(path: string): Promise<boolean>;
|
|
16
18
|
export declare function hydrateDocPath(destDocPath: string, entityCondition: Record<string, QueryCondition>): Promise<string[]>;
|
|
19
|
+
export {};
|
package/lib/utils/paths.js
CHANGED
|
@@ -4,19 +4,8 @@ exports.hydrateDocPath = exports.expandAndGroupDocPaths = exports.filterSubDocPa
|
|
|
4
4
|
const query_1 = require("./query");
|
|
5
5
|
const index_1 = require("../index");
|
|
6
6
|
exports._mockable = {
|
|
7
|
-
filterSubDocPathsByEntity
|
|
8
|
-
|
|
9
|
-
const paths = Object.values(index_1.docPaths);
|
|
10
|
-
// Find the doc paths of the excluded entities
|
|
11
|
-
const excludePaths = excludeEntities === null || excludeEntities === void 0 ? void 0 : excludeEntities.map((excludeEntity) => index_1.docPaths[excludeEntity]);
|
|
12
|
-
return paths.filter((p) => {
|
|
13
|
-
// Check if the path starts with the given entity's doc path
|
|
14
|
-
const startsWithPath = p.startsWith(path);
|
|
15
|
-
// Check if the path starts with any of the excluded entity's doc paths
|
|
16
|
-
const startsWithExcludedPath = excludePaths === null || excludePaths === void 0 ? void 0 : excludePaths.some((excludePath) => p.startsWith(excludePath));
|
|
17
|
-
return startsWithPath && !startsWithExcludedPath;
|
|
18
|
-
});
|
|
19
|
-
},
|
|
7
|
+
filterSubDocPathsByEntity,
|
|
8
|
+
doesPathExists,
|
|
20
9
|
};
|
|
21
10
|
function findMatchingDocPathRegex(docPath) {
|
|
22
11
|
for (const key in index_1.docPathsRegex) {
|
|
@@ -28,7 +17,17 @@ function findMatchingDocPathRegex(docPath) {
|
|
|
28
17
|
}
|
|
29
18
|
exports.findMatchingDocPathRegex = findMatchingDocPathRegex;
|
|
30
19
|
function filterSubDocPathsByEntity(entity, excludeEntities) {
|
|
31
|
-
|
|
20
|
+
const path = index_1.docPaths[entity];
|
|
21
|
+
const paths = Object.values(index_1.docPaths);
|
|
22
|
+
// Find the doc paths of the excluded entities
|
|
23
|
+
const excludePaths = excludeEntities === null || excludeEntities === void 0 ? void 0 : excludeEntities.map((excludeEntity) => index_1.docPaths[excludeEntity]);
|
|
24
|
+
return paths.filter((p) => {
|
|
25
|
+
// Check if the path starts with the given entity's doc path
|
|
26
|
+
const startsWithPath = p.startsWith(path);
|
|
27
|
+
// Check if the path starts with any of the excluded entity's doc paths
|
|
28
|
+
const startsWithExcludedPath = excludePaths === null || excludePaths === void 0 ? void 0 : excludePaths.some((excludePath) => p.startsWith(excludePath));
|
|
29
|
+
return startsWithPath && !startsWithExcludedPath;
|
|
30
|
+
});
|
|
32
31
|
}
|
|
33
32
|
exports.filterSubDocPathsByEntity = filterSubDocPathsByEntity;
|
|
34
33
|
async function expandAndGroupDocPaths(startingDocPath, entityCondition, excludeEntities) {
|
|
@@ -38,7 +37,7 @@ async function expandAndGroupDocPaths(startingDocPath, entityCondition, excludeE
|
|
|
38
37
|
return groupedPaths;
|
|
39
38
|
}
|
|
40
39
|
const entityDocPath = index_1.docPaths[entity];
|
|
41
|
-
const subDocPaths = filterSubDocPathsByEntity(entity, excludeEntities);
|
|
40
|
+
const subDocPaths = exports._mockable.filterSubDocPathsByEntity(entity, excludeEntities);
|
|
42
41
|
const values = Object.values(subDocPaths).map((p) => p.replace(entityDocPath, startingDocPath));
|
|
43
42
|
const sortedValues = values.sort();
|
|
44
43
|
const newPathMap = new Map();
|
|
@@ -82,6 +81,10 @@ async function expandAndGroupDocPaths(startingDocPath, entityCondition, excludeE
|
|
|
82
81
|
return groupedPaths;
|
|
83
82
|
}
|
|
84
83
|
exports.expandAndGroupDocPaths = expandAndGroupDocPaths;
|
|
84
|
+
async function doesPathExists(path) {
|
|
85
|
+
const doc = await index_1.db.doc(path).get();
|
|
86
|
+
return doc.exists;
|
|
87
|
+
}
|
|
85
88
|
async function hydrateDocPath(destDocPath, entityCondition) {
|
|
86
89
|
const pathSegments = destDocPath.split("/");
|
|
87
90
|
const documentPaths = [];
|
|
@@ -103,8 +106,7 @@ async function hydrateDocPath(destDocPath, entityCondition) {
|
|
|
103
106
|
const path = segments.join("/");
|
|
104
107
|
if (idx < segments.length - 1) {
|
|
105
108
|
// This means that the path contains hard coded ids, so we need to check if that pat exists in the database
|
|
106
|
-
|
|
107
|
-
if (!doc.exists) {
|
|
109
|
+
if (!await exports._mockable.doesPathExists(path)) {
|
|
108
110
|
console.error(`Document ${path} does not exist. Skipping...`);
|
|
109
111
|
continue;
|
|
110
112
|
}
|
package/lib/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":";;;AACA,mCAAiC;AACjC,
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/query.js
CHANGED
|
@@ -5,7 +5,7 @@ const index_1 = require("../index");
|
|
|
5
5
|
const firebase_admin_1 = require("firebase-admin");
|
|
6
6
|
async function fetchIds(collectionPath, condition) {
|
|
7
7
|
const ids = [];
|
|
8
|
-
const baseQuery = index_1.
|
|
8
|
+
const baseQuery = index_1.db.collection(collectionPath).select(firebase_admin_1.firestore.FieldPath.documentId());
|
|
9
9
|
async function executeQuery(query) {
|
|
10
10
|
const querySnapshot = await query.get();
|
|
11
11
|
querySnapshot.docs.forEach((doc) => {
|
package/lib/utils/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/utils/query.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/utils/query.ts"],"names":[],"mappings":";;;AAAA,oCAA4B;AAC5B,mDAAyC;AAKlC,KAAK,UAAU,QAAQ,CAAC,cAAsB,EAAE,SAA0B;IAC/E,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,SAAS,GAAG,UAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,0BAAS,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;IAEzF,KAAK,UAAU,YAAY,CAAC,KAA0B;QACpD,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC;QACxC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IACE,SAAS;QACP,CACE,SAAS,CAAC,QAAQ,KAAK,IAAI;YACzB,SAAS,CAAC,QAAQ,KAAK,QAAQ;YAC/B,SAAS,CAAC,QAAQ,KAAK,oBAAoB,CAC9C,EACH;QACA,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC;QAC/B,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE;YACjD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;SAC7C;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC9E,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KAC7B;SAAM;QACL,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,IAAI,SAAS,EAAE;YACb,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;SAC/E;QACD,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;KAC3B;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAvCD,4BAuCC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emberflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "A Firebase Cloud Functions library for handling document changes in a structured way",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.js",
|
|
@@ -33,5 +33,9 @@
|
|
|
33
33
|
"ts-jest": "^29.0.5",
|
|
34
34
|
"typescript": "^4.9.0"
|
|
35
35
|
},
|
|
36
|
-
"private": false
|
|
36
|
+
"private": false,
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@google-cloud/billing": "^3.4.0",
|
|
39
|
+
"@google-cloud/functions": "^2.5.0"
|
|
40
|
+
}
|
|
37
41
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
rules_version = '2';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
service cloud.firestore {
|
|
5
|
+
match /databases/{database}/documents {
|
|
6
|
+
// Deny read and write access by default
|
|
7
|
+
match /{document=**} {
|
|
8
|
+
allow read, write: if false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Allow read and write access to authenticated users for documents within the users collection
|
|
12
|
+
match /users/{uid}/{document=**} {
|
|
13
|
+
allow read, write: if request.auth != null && request.auth.uid == uid;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|