emberflow 1.3.8 → 1.3.42
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/db-structure.d.ts +2 -7
- package/lib/db-structure.js +1 -6
- package/lib/db-structure.js.map +1 -1
- package/lib/index-utils.d.ts +10 -5
- package/lib/index-utils.js +87 -122
- package/lib/index-utils.js.map +1 -1
- package/lib/index.d.ts +7 -0
- package/lib/index.js +85 -42
- package/lib/index.js.map +1 -1
- package/lib/logics/view-logics.d.ts +22 -2
- package/lib/logics/view-logics.js +107 -53
- package/lib/logics/view-logics.js.map +1 -1
- package/lib/sample-custom/db-structure.d.ts +16 -8
- package/lib/sample-custom/db-structure.js +17 -9
- package/lib/sample-custom/db-structure.js.map +1 -1
- package/lib/tests/index-utils.test.js +233 -137
- package/lib/tests/index-utils.test.js.map +1 -1
- package/lib/tests/index.test.js +21 -17
- package/lib/tests/index.test.js.map +1 -1
- package/lib/tests/logics/view-logics.test.js +203 -24
- package/lib/tests/logics/view-logics.test.js.map +1 -1
- package/lib/tests/utils/distribution.test.d.ts +1 -0
- package/lib/tests/utils/distribution.test.js +206 -0
- package/lib/tests/utils/distribution.test.js.map +1 -0
- package/lib/tests/utils/forms.test.d.ts +1 -0
- package/lib/tests/utils/forms.test.js +113 -0
- package/lib/tests/utils/forms.test.js.map +1 -0
- package/lib/tests/utils/misc.test.js +138 -0
- package/lib/tests/utils/misc.test.js.map +1 -1
- package/lib/tests/utils/paths.test.js +6 -5
- package/lib/tests/utils/paths.test.js.map +1 -1
- package/lib/tests/utils/pubsub.test.d.ts +1 -0
- package/lib/tests/utils/pubsub.test.js +109 -0
- package/lib/tests/utils/pubsub.test.js.map +1 -0
- package/lib/types.d.ts +7 -1
- package/lib/utils/bill-protect.d.ts +2 -1
- package/lib/utils/bill-protect.js +1 -1
- package/lib/utils/bill-protect.js.map +1 -1
- package/lib/utils/distribution.d.ts +9 -0
- package/lib/utils/distribution.js +119 -0
- package/lib/utils/distribution.js.map +1 -0
- package/lib/utils/forms.d.ts +4 -2
- package/lib/utils/forms.js +32 -101
- package/lib/utils/forms.js.map +1 -1
- package/lib/utils/misc.d.ts +17 -0
- package/lib/utils/misc.js +81 -1
- package/lib/utils/misc.js.map +1 -1
- package/lib/utils/pubsub.d.ts +9 -0
- package/lib/utils/pubsub.js +32 -0
- package/lib/utils/pubsub.js.map +1 -0
- package/package.json +3 -2
- package/src/sample-custom/db-structure.ts +17 -9
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onMessageInstructionsQueue = exports.queueInstructions = exports.onMessageForDistributionQueue = exports.queueForDistributionLater = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const index_utils_1 = require("../index-utils");
|
|
6
|
+
const pubsub_1 = require("./pubsub");
|
|
7
|
+
const queueForDistributionLater = async (...logicResultDocs) => {
|
|
8
|
+
const topic = index_1.pubsub.topic(index_1.FOR_DISTRIBUTION_TOPIC_NAME);
|
|
9
|
+
try {
|
|
10
|
+
for (const logicResultDoc of logicResultDocs) {
|
|
11
|
+
const messageId = await topic.publishMessage({ json: logicResultDoc });
|
|
12
|
+
console.log(`Message ${messageId} published.`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
console.error(`Received error while publishing: ${error.message}`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.error("An unknown error occurred during publishing");
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.queueForDistributionLater = queueForDistributionLater;
|
|
26
|
+
async function onMessageForDistributionQueue(event) {
|
|
27
|
+
try {
|
|
28
|
+
const logicResultDoc = event.data.message.json;
|
|
29
|
+
console.log("Received user logic result doc:", logicResultDoc);
|
|
30
|
+
console.info("Running For Distribution");
|
|
31
|
+
const { priority = "normal" } = logicResultDoc;
|
|
32
|
+
if (priority === "high") {
|
|
33
|
+
await (0, index_utils_1.distributeDoc)(logicResultDoc);
|
|
34
|
+
}
|
|
35
|
+
else if (priority === "normal") {
|
|
36
|
+
logicResultDoc.priority = "high";
|
|
37
|
+
await (0, exports.queueForDistributionLater)(logicResultDoc);
|
|
38
|
+
}
|
|
39
|
+
else if (priority === "low") {
|
|
40
|
+
logicResultDoc.priority = "normal";
|
|
41
|
+
await (0, exports.queueForDistributionLater)(logicResultDoc);
|
|
42
|
+
}
|
|
43
|
+
return "Processed for distribution later";
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.error("PubSub message was not JSON", e);
|
|
47
|
+
throw new Error("No json in message");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.onMessageForDistributionQueue = onMessageForDistributionQueue;
|
|
51
|
+
async function queueInstructions(dstPath, instructions) {
|
|
52
|
+
const topic = index_1.pubsub.topic(index_1.INSTRUCTIONS_TOPIC_NAME);
|
|
53
|
+
try {
|
|
54
|
+
const messageId = await topic.publishMessage({ json: { dstPath, instructions } });
|
|
55
|
+
console.log(`Message ${messageId} published.`);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
console.error(`Received error while publishing: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.error("An unknown error occurred during publishing");
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.queueInstructions = queueInstructions;
|
|
68
|
+
async function onMessageInstructionsQueue(event) {
|
|
69
|
+
if (await pubsub_1.pubsubUtils.isProcessed(index_1.INSTRUCTIONS_TOPIC_NAME, event.id)) {
|
|
70
|
+
console.log("Skipping duplicate message");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const instructionsMessage = event.data.message.json;
|
|
75
|
+
console.log("Received user logic result doc:", instructionsMessage);
|
|
76
|
+
console.info("Running For Distribution");
|
|
77
|
+
const { dstPath, instructions } = instructionsMessage;
|
|
78
|
+
const updateData = {};
|
|
79
|
+
for (const [property, instruction] of Object.entries(instructions)) {
|
|
80
|
+
if (instruction === "++") {
|
|
81
|
+
updateData[property] = index_1.admin.firestore.FieldValue.increment(1);
|
|
82
|
+
}
|
|
83
|
+
else if (instruction === "--") {
|
|
84
|
+
updateData[property] = index_1.admin.firestore.FieldValue.increment(-1);
|
|
85
|
+
}
|
|
86
|
+
else if (instruction.startsWith("+")) {
|
|
87
|
+
const incrementValue = parseInt(instruction.slice(1));
|
|
88
|
+
if (isNaN(incrementValue)) {
|
|
89
|
+
console.log(`Invalid increment value ${instruction} for property ${property}`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
updateData[property] = index_1.admin.firestore.FieldValue.increment(incrementValue);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (instruction.startsWith("-")) {
|
|
96
|
+
const decrementValue = parseInt(instruction.slice(1));
|
|
97
|
+
if (isNaN(decrementValue)) {
|
|
98
|
+
console.log(`Invalid decrement value ${instruction} for property ${property}`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
updateData[property] = index_1.admin.firestore.FieldValue.increment(-decrementValue);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.log(`Invalid instruction ${instruction} for property ${property}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const dstDocRef = index_1.db.doc(dstPath);
|
|
109
|
+
await dstDocRef.set(updateData, { merge: true });
|
|
110
|
+
await pubsub_1.pubsubUtils.trackProcessedIds(index_1.INSTRUCTIONS_TOPIC_NAME, event.id);
|
|
111
|
+
return "Processed instructions";
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
console.error("PubSub message was not JSON", e);
|
|
115
|
+
throw new Error("No json in message");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.onMessageInstructionsQueue = onMessageInstructionsQueue;
|
|
119
|
+
//# sourceMappingURL=distribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribution.js","sourceRoot":"","sources":["../../src/utils/distribution.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/forms.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { FormData } from "emberflow-admin-client/lib/types";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { CloudEvent } from "firebase-functions/lib/v2/core";
|
|
3
|
+
import { MessagePublishedData } from "firebase-functions/lib/v2/providers/pubsub";
|
|
4
|
+
export declare function queueSubmitForm(formData: FormData): Promise<string>;
|
|
5
|
+
export declare function onMessageSubmitFormQueue(event: CloudEvent<MessagePublishedData>): Promise<"Processed form data" | undefined>;
|
package/lib/utils/forms.js
CHANGED
|
@@ -1,113 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const lib_1 = require("emberflow-admin-client/lib");
|
|
3
|
+
exports.onMessageSubmitFormQueue = exports.queueSubmitForm = void 0;
|
|
5
4
|
const index_1 = require("../index");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
function waitForSubmitFormQueueToEmpty() {
|
|
15
|
-
// If the queue is already empty and there are no active submissions, resolve immediately
|
|
16
|
-
if (!running) {
|
|
17
|
-
return Promise.resolve();
|
|
5
|
+
const lib_1 = require("emberflow-admin-client/lib");
|
|
6
|
+
const pubsub_1 = require("./pubsub");
|
|
7
|
+
async function queueSubmitForm(formData) {
|
|
8
|
+
const topic = index_1.pubsub.topic(index_1.SUBMIT_FORM_TOPIC_NAME);
|
|
9
|
+
try {
|
|
10
|
+
const messageId = await topic.publishMessage({ json: formData });
|
|
11
|
+
console.log(`Message ${messageId} published.`);
|
|
12
|
+
return messageId;
|
|
18
13
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error instanceof Error) {
|
|
16
|
+
console.error(`Received error while publishing: ${error.message}`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.error("An unknown error occurred during publishing");
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
24
22
|
}
|
|
25
|
-
// Reset queueEmptyPromise to ensure a new promise is created next time
|
|
26
|
-
queueEmptyPromise.then(() => {
|
|
27
|
-
queueEmptyPromise = undefined;
|
|
28
|
-
});
|
|
29
|
-
return queueEmptyPromise;
|
|
30
|
-
}
|
|
31
|
-
exports.waitForSubmitFormQueueToEmpty = waitForSubmitFormQueueToEmpty;
|
|
32
|
-
async function queueSubmitForm(formData) {
|
|
33
|
-
// Add the formData and the current timestamp to the queue
|
|
34
|
-
console.log("Queueing form submission", formData);
|
|
35
|
-
await index_1.db.runTransaction(async (transaction) => {
|
|
36
|
-
const queueRef = index_1.db.collection("@internal/submitFormExecutor/queue");
|
|
37
|
-
const docRef = queueRef.doc();
|
|
38
|
-
transaction.set(docRef, { formData, timestamp: Date.now() });
|
|
39
|
-
});
|
|
40
|
-
// Process the queue
|
|
41
|
-
processQueue();
|
|
42
23
|
}
|
|
43
24
|
exports.queueSubmitForm = queueSubmitForm;
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const queueRef = index_1.db.collection("@internal/submitFormExecutor/queue");
|
|
48
|
-
const queueDoc = await transaction.get(execRef);
|
|
49
|
-
({ activeCount, maxConcurrentSubmit } = queueDoc.data() || { activeCount: 0, maxConcurrentSubmit: 10 });
|
|
50
|
-
if (queue.length <= 1) {
|
|
51
|
-
const queryRef = queueRef.orderBy("timestamp", "asc")
|
|
52
|
-
.limit(2 * maxConcurrentSubmit);
|
|
53
|
-
const queueSnapshot = await transaction.get(queryRef);
|
|
54
|
-
queueSnapshot.forEach((doc) => {
|
|
55
|
-
queue.push(Object.assign(Object.assign({}, doc.data()), { "@id": doc.id }));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
async function processQueue() {
|
|
61
|
-
await updateQueueInfo();
|
|
62
|
-
console.debug("maxConcurrentSubmit", maxConcurrentSubmit);
|
|
63
|
-
if (!running && activeCount > 0) {
|
|
64
|
-
console.debug("Another executor is already running");
|
|
25
|
+
async function onMessageSubmitFormQueue(event) {
|
|
26
|
+
if (await pubsub_1.pubsubUtils.isProcessed(index_1.SUBMIT_FORM_TOPIC_NAME, event.id)) {
|
|
27
|
+
console.log("Skipping duplicate event");
|
|
65
28
|
return;
|
|
66
29
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
transaction.delete(queueRef.doc(queueItem["@id"]));
|
|
79
|
-
transaction.set(execRef, { activeCount: index_1.admin.firestore.FieldValue.increment(1) }, { merge: true });
|
|
80
|
-
});
|
|
81
|
-
const { formData, timestamp } = queueItem;
|
|
82
|
-
// Submit the form
|
|
83
|
-
_submitForm(formData).then(async () => {
|
|
84
|
-
// Decrement the active count
|
|
85
|
-
const execRef = index_1.db.doc("@internal/submitFormExecutor");
|
|
86
|
-
await execRef.set({ activeCount: index_1.admin.firestore.FieldValue.increment(-1) }, { merge: true });
|
|
87
|
-
await updateQueueInfo();
|
|
88
|
-
// Check if the queue is empty and all submissions have been processed
|
|
89
|
-
if (queue.length === 0 && activeCount === 0) {
|
|
90
|
-
resolveQueueEmpty(); // Resolve the waitForQueueToEmpty promise
|
|
91
|
-
queueEmptyPromise = undefined;
|
|
92
|
-
running = false;
|
|
93
|
-
}
|
|
94
|
-
// Calculate the time spent in the queue
|
|
95
|
-
const timeSpent = (Date.now() - timestamp) / 1000; // time in seconds
|
|
96
|
-
// Log the time spent in the queue
|
|
97
|
-
console.log(`formData spent ${timeSpent.toFixed(2)} seconds in the queue.`);
|
|
98
|
-
// Process the next item in the queue
|
|
99
|
-
processQueue();
|
|
100
|
-
});
|
|
30
|
+
try {
|
|
31
|
+
const formData = event.data.message.json;
|
|
32
|
+
console.log("Received form submission:", formData);
|
|
33
|
+
// TODO: Let's make status handler optional
|
|
34
|
+
await (0, lib_1.submitForm)(formData);
|
|
35
|
+
await pubsub_1.pubsubUtils.trackProcessedIds(index_1.SUBMIT_FORM_TOPIC_NAME, event.id);
|
|
36
|
+
return "Processed form data";
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
console.error("PubSub message was not JSON", e);
|
|
40
|
+
throw new Error("No json in message");
|
|
101
41
|
}
|
|
102
42
|
}
|
|
103
|
-
|
|
104
|
-
return new Promise((resolve) => {
|
|
105
|
-
(0, lib_1.submitForm)(formData, (status, data, isLastUpdate) => {
|
|
106
|
-
console.log("status", status, "data", data, "isLastUpdate", isLastUpdate);
|
|
107
|
-
if (isLastUpdate) {
|
|
108
|
-
resolve();
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
}
|
|
43
|
+
exports.onMessageSubmitFormQueue = onMessageSubmitFormQueue;
|
|
113
44
|
//# sourceMappingURL=forms.js.map
|
package/lib/utils/forms.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forms.js","sourceRoot":"","sources":["../../src/utils/forms.ts"],"names":[],"mappings":";;;AACA,oDAAsD;AACtD,
|
|
1
|
+
{"version":3,"file":"forms.js","sourceRoot":"","sources":["../../src/utils/forms.ts"],"names":[],"mappings":";;;AACA,oCAAwD;AAGxD,oDAAsD;AACtD,qCAAqC;AAE9B,KAAK,UAAU,eAAe,CAAC,QAAkB;IACtD,MAAM,KAAK,GAAG,cAAM,CAAC,KAAK,CAAC,8BAAsB,CAAC,CAAC;IAEnD,IAAI;QACF,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,WAAW,SAAS,aAAa,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC;KAClB;IAAC,OAAO,KAAc,EAAE;QACvB,IAAI,KAAK,YAAY,KAAK,EAAE;YAC1B,OAAO,CAAC,KAAK,CAAC,oCAAoC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;SACpE;aAAM;YACL,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAC9D;QACD,MAAM,KAAK,CAAC;KACb;AACH,CAAC;AAfD,0CAeC;AAEM,KAAK,UAAU,wBAAwB,CAAC,KAAuC;IACpF,IAAI,MAAM,oBAAW,CAAC,WAAW,CAAC,8BAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE;QACnE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,OAAO;KACR;IACD,IAAI;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;QAEnD,4CAA4C;QAC5C,MAAM,IAAA,gBAAU,EAAC,QAAQ,CAAC,CAAC;QAE3B,MAAM,oBAAW,CAAC,iBAAiB,CAAC,8BAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACtE,OAAO,qBAAqB,CAAC;KAC9B;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;KACvC;AACH,CAAC;AAlBD,4DAkBC"}
|
package/lib/utils/misc.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/// <reference types="express" />
|
|
2
|
+
import { firestore } from "firebase-admin";
|
|
3
|
+
import { Request, Response } from "firebase-functions";
|
|
4
|
+
import Query = firestore.Query;
|
|
1
5
|
export declare function deepEqual(a: any, b: any): boolean;
|
|
2
6
|
export declare function computeHashCode(str: string): string;
|
|
3
7
|
export declare function sleep(ms: number): Promise<unknown>;
|
|
8
|
+
export declare function deleteForms(request: Request, response: Response): void;
|
|
9
|
+
export declare class LimitedSet<T> {
|
|
10
|
+
private maxLength;
|
|
11
|
+
private _set;
|
|
12
|
+
private _queue;
|
|
13
|
+
constructor(maxLength: number);
|
|
14
|
+
add(item: T): void;
|
|
15
|
+
has(item: T): boolean;
|
|
16
|
+
delete(item: T): boolean;
|
|
17
|
+
get set(): Set<T>;
|
|
18
|
+
get queue(): T[];
|
|
19
|
+
}
|
|
20
|
+
export declare function deleteCollection(query: Query): Promise<void>;
|
package/lib/utils/misc.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sleep = exports.computeHashCode = exports.deepEqual = void 0;
|
|
3
|
+
exports.deleteCollection = exports.LimitedSet = exports.deleteForms = exports.sleep = exports.computeHashCode = exports.deepEqual = void 0;
|
|
4
4
|
const firebase_admin_1 = require("firebase-admin");
|
|
5
|
+
const index_1 = require("../index");
|
|
5
6
|
var Timestamp = firebase_admin_1.firestore.Timestamp;
|
|
6
7
|
var GeoPoint = firebase_admin_1.firestore.GeoPoint;
|
|
8
|
+
const batch_1 = require("./batch");
|
|
7
9
|
function isObject(item) {
|
|
8
10
|
return (typeof item === "object" && !Array.isArray(item) && item !== null);
|
|
9
11
|
}
|
|
@@ -66,4 +68,82 @@ async function sleep(ms) {
|
|
|
66
68
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
67
69
|
}
|
|
68
70
|
exports.sleep = sleep;
|
|
71
|
+
function deleteForms(request, response) {
|
|
72
|
+
const userId = request.query.userId;
|
|
73
|
+
if (!userId) {
|
|
74
|
+
response.status(400).send("No ID provided");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const ref = index_1.rtdb.ref(`forms/${userId}`);
|
|
78
|
+
ref.remove()
|
|
79
|
+
.then(() => {
|
|
80
|
+
response.send(`Data with ID ${userId} deleted`);
|
|
81
|
+
})
|
|
82
|
+
.catch((error) => {
|
|
83
|
+
console.error("Error deleting data:", error);
|
|
84
|
+
response.status(500).send("Internal Server Error");
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.deleteForms = deleteForms;
|
|
88
|
+
class LimitedSet {
|
|
89
|
+
constructor(maxLength) {
|
|
90
|
+
this.maxLength = maxLength;
|
|
91
|
+
this._set = new Set();
|
|
92
|
+
this._queue = [];
|
|
93
|
+
}
|
|
94
|
+
add(item) {
|
|
95
|
+
if (this._set.has(item)) {
|
|
96
|
+
return; // Item already exists, no need to add
|
|
97
|
+
}
|
|
98
|
+
if (this._queue.length === this.maxLength) {
|
|
99
|
+
const oldestItem = this._queue.shift(); // Remove the oldest item from the queue
|
|
100
|
+
if (oldestItem) {
|
|
101
|
+
this._set.delete(oldestItem); // Remove the oldest item from the set
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this._queue.push(item); // Add the new item to the queue
|
|
105
|
+
this._set.add(item); // Add the new item to the set
|
|
106
|
+
}
|
|
107
|
+
has(item) {
|
|
108
|
+
return this._set.has(item);
|
|
109
|
+
}
|
|
110
|
+
delete(item) {
|
|
111
|
+
if (!this._set.has(item)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
this._set.delete(item);
|
|
115
|
+
const index = this._queue.indexOf(item);
|
|
116
|
+
this._queue.splice(index, 1);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
get set() {
|
|
120
|
+
return this._set;
|
|
121
|
+
}
|
|
122
|
+
get queue() {
|
|
123
|
+
return this._queue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.LimitedSet = LimitedSet;
|
|
127
|
+
async function deleteCollection(query) {
|
|
128
|
+
query = query.limit(500);
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
deleteQueryBatch(query, resolve).catch(reject);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
exports.deleteCollection = deleteCollection;
|
|
134
|
+
async function deleteQueryBatch(query, resolve) {
|
|
135
|
+
const snapshot = await query.get();
|
|
136
|
+
if (snapshot.size === 0) {
|
|
137
|
+
resolve();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const batch = batch_1.BatchUtil.getInstance();
|
|
141
|
+
snapshot.docs.forEach((doc) => {
|
|
142
|
+
batch.deleteDoc(doc.ref);
|
|
143
|
+
});
|
|
144
|
+
await batch.commit();
|
|
145
|
+
process.nextTick(() => {
|
|
146
|
+
deleteQueryBatch(query, resolve);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
69
149
|
//# 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;
|
|
1
|
+
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/utils/misc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ScheduledEvent } from "firebase-functions/lib/v2/providers/scheduler";
|
|
2
|
+
declare function trackProcessedIds(topicName: string, id: string): Promise<void>;
|
|
3
|
+
declare function isProcessed(topicName: string, id: string): Promise<boolean>;
|
|
4
|
+
export declare const pubsubUtils: {
|
|
5
|
+
trackProcessedIds: typeof trackProcessedIds;
|
|
6
|
+
isProcessed: typeof isProcessed;
|
|
7
|
+
};
|
|
8
|
+
export declare function cleanPubSubProcessedIds(event: ScheduledEvent): Promise<void>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cleanPubSubProcessedIds = exports.pubsubUtils = void 0;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const misc_1 = require("./misc");
|
|
6
|
+
async function trackProcessedIds(topicName, id) {
|
|
7
|
+
const docRef = index_1.db.doc(`@topics/${topicName}/processedIds/${id}`);
|
|
8
|
+
await docRef.set({ timestamp: new Date() });
|
|
9
|
+
}
|
|
10
|
+
async function isProcessed(topicName, id) {
|
|
11
|
+
const docRef = index_1.db.doc(`@topics/${topicName}/processedIds/${id}`);
|
|
12
|
+
const doc = await docRef.get();
|
|
13
|
+
return doc.exists;
|
|
14
|
+
}
|
|
15
|
+
exports.pubsubUtils = {
|
|
16
|
+
trackProcessedIds,
|
|
17
|
+
isProcessed,
|
|
18
|
+
};
|
|
19
|
+
async function cleanPubSubProcessedIds(event) {
|
|
20
|
+
console.info("Running cleanPubSubProcessedIds");
|
|
21
|
+
const topicsSnapshot = await index_1.db.collection("@topics").get();
|
|
22
|
+
let i = 0;
|
|
23
|
+
for (const topicDoc of topicsSnapshot.docs) {
|
|
24
|
+
const query = topicDoc.ref.collection("processedIds")
|
|
25
|
+
.where("timestamp", "<", new Date(Date.now() - 1000 * 60 * 60 * 24 * 7));
|
|
26
|
+
await (0, misc_1.deleteCollection)(query);
|
|
27
|
+
i++;
|
|
28
|
+
}
|
|
29
|
+
console.info(`Cleaned ${i} topics of processedIds`);
|
|
30
|
+
}
|
|
31
|
+
exports.cleanPubSubProcessedIds = cleanPubSubProcessedIds;
|
|
32
|
+
//# sourceMappingURL=pubsub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../../src/utils/pubsub.ts"],"names":[],"mappings":";;;AAAA,oCAA4B;AAC5B,iCAAwC;AAGxC,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,EAAU;IAC5D,MAAM,MAAM,GAAG,UAAE,CAAC,GAAG,CAAC,WAAW,SAAS,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,CAAC,GAAG,CAAC,EAAC,SAAS,EAAE,IAAI,IAAI,EAAE,EAAC,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,EAAU;IACtD,MAAM,MAAM,GAAG,UAAE,CAAC,GAAG,CAAC,WAAW,SAAS,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IAC/B,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC;AAEY,QAAA,WAAW,GAAG;IACzB,iBAAiB;IACjB,WAAW;CACZ,CAAC;AAEK,KAAK,UAAU,uBAAuB,CAAC,KAAqB;IACjE,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,UAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;IAC5D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC;aAClD,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3E,MAAM,IAAA,uBAAgB,EAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,EAAE,CAAC;KACL;IACD,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;AACtD,CAAC;AAXD,0DAWC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emberflow",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.42",
|
|
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",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@google-cloud/billing": "^3.4.0",
|
|
39
39
|
"@google-cloud/functions": "^2.5.0",
|
|
40
|
-
"
|
|
40
|
+
"@google-cloud/pubsub": "^4.0.7",
|
|
41
|
+
"emberflow-admin-client": "^1.1.5"
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -6,21 +6,29 @@ export enum Entity {
|
|
|
6
6
|
// Add your custom entities below
|
|
7
7
|
Feed = "feed",
|
|
8
8
|
Friend = "friend",
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
TopicAlgolia = "topic-algolia",
|
|
9
|
+
Server = "server",
|
|
10
|
+
Channel = "channel",
|
|
11
|
+
Member = "member",
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
// Map your custom entities to dbStructure below.
|
|
16
15
|
// Do not remove users and [Entity.User]
|
|
17
16
|
// by default, view matches the id attribute of the view so make the sure that a view has an id
|
|
18
17
|
export const dbStructure = {
|
|
19
|
-
|
|
20
|
-
[Entity.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
servers: {
|
|
19
|
+
[Entity.Server]: {
|
|
20
|
+
createdBy: view(Entity.User, ["name", "email"]),
|
|
21
|
+
channels: {
|
|
22
|
+
[Entity.Channel]: {
|
|
23
|
+
"createdBy": view(Entity.User, ["name", "email"]),
|
|
24
|
+
"members": {
|
|
25
|
+
[view(Entity.User, ["name"])]: {},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
members: {
|
|
30
|
+
[Entity.Member]: {
|
|
31
|
+
[view(Entity.User, ["name"])]: {},
|
|
24
32
|
},
|
|
25
33
|
},
|
|
26
34
|
},
|