@webtypen/webframez-core 0.3.68 → 0.3.69
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 +32 -0
- package/dist/Api/ApiFunctionUtils.js +5 -4
- package/dist/Commands/QueueWorkerCommand.js +9 -19
- package/dist/DataBuilder/DataBuilder.d.ts +7 -6
- package/dist/DataBuilder/DataBuilder.js +4 -2
- package/dist/DataBuilder/DataBuilderController.js +4 -4
- package/dist/Database/BaseDBDriver.d.ts +4 -0
- package/dist/Database/BaseDBDriver.js +11 -0
- package/dist/Database/DBConnection.d.ts +7 -2
- package/dist/Database/DBConnection.js +33 -12
- package/dist/Database/DatabaseAdapter.d.ts +42 -0
- package/dist/Database/DatabaseAdapter.js +2 -0
- package/dist/Datatable/Datatable.d.ts +2 -2
- package/dist/Datatable/Datatable.js +6 -17
- package/dist/Functions/PaginationFunctions.js +1 -1
- package/dist/Notifications/Notification.d.ts +4 -4
- package/dist/Notifications/NotificationService.d.ts +11 -11
- package/dist/Notifications/NotificationService.js +29 -43
- package/dist/Notifications/NotificationsOutputChannelsJob.js +4 -8
- package/dist/Queue/Queue.js +2 -2
- package/dist/Queue/QueueJob.d.ts +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -21,6 +21,38 @@ This README reflects the current API in this repository and focuses on:
|
|
|
21
21
|
npm i @webtypen/webframez-core
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
## Database drivers (from 0.3.69)
|
|
25
|
+
|
|
26
|
+
The core has no MongoDB/BSON dependency. HTTP routing and database-independent
|
|
27
|
+
commands work without installing or registering a database driver. Database access
|
|
28
|
+
requires a registered driver; missing configuration or capabilities fail explicitly.
|
|
29
|
+
|
|
30
|
+
For MongoDB, use `@webtypen/webframez-dbdriver-mongodb >=0.0.11` and register
|
|
31
|
+
`MongoDBDriver` with `DBDrivers.register("mongodb", MongoDBDriver)` before database
|
|
32
|
+
features are used. Upgrade the driver before the core. Applications that directly
|
|
33
|
+
import MongoDB must declare their own `mongodb` dependency.
|
|
34
|
+
|
|
35
|
+
Driver authors implement `idAdapter` for ID creation, normalization, validation and
|
|
36
|
+
comparison. ID conversion does not open a connection. `Model.objectId(...)` keeps
|
|
37
|
+
its existing name and driver-defined return value for compatibility.
|
|
38
|
+
|
|
39
|
+
Datatables, DataBuilder, pagination, queues and notifications use the optional
|
|
40
|
+
`documentStore(client): DocumentDatabase` capability. Its filters, updates and
|
|
41
|
+
aggregation stages use MongoDB-style document operators; another driver must
|
|
42
|
+
translate them or report that this capability is unsupported. This is not a SQL
|
|
43
|
+
query abstraction. `findOneAndUpdate` must atomically select/update one record and
|
|
44
|
+
return the document or `null`, never a native result wrapper. No read-then-write
|
|
45
|
+
fallback is allowed for queue or notification claims.
|
|
46
|
+
|
|
47
|
+
Verification after `npm run build`:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
node --test -r ts-node/register/transpile-only src/Database/DatabaseAdapter.spec.ts src/Commands/QueueWorkerCommand.spec.ts src/Notifications/NotificationService.spec.ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The tests include an HTTP server with MongoDB, BSON and all database-driver imports
|
|
54
|
+
blocked, and a numeric-ID test driver that never opens a database connection.
|
|
55
|
+
|
|
24
56
|
## Agent-Regeln fuer Codex und Copilot
|
|
25
57
|
|
|
26
58
|
Das Paket enthaelt unter agents/webframez_rules.md empfohlene Arbeitsregeln fuer AI-Coding-Agents in Webframez-Projekten.
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.instantiateApiFunction = exports.instantiateApiScope = exports.assertUniqueApiFunctionKeys = exports.createApiFrameworkRequest = exports.toApiFunctionPayload = exports.toApiFunctionHttpResult = exports.apiFunctionParamToJsonSchema = exports.apiFunctionParamsToJsonSchema = exports.coerceApiFunctionParam = exports.validateApiFunctionParams = exports.runApiScopeRegistrationMiddleware = exports.runApiScopeGroupMiddleware = exports.runApiScopesGroupMiddleware = exports.runApiScopeMiddleware = exports.collectApiScopeRegistrations = exports.instantiateApiScopesGroup = exports.isApiScopesGroupInstance = exports.normalizeApiScopesGroupProvider = exports.getApiFunctionClasses = exports.normalizeApiFunctionProvider = exports.isPlainApiObject = exports.getApiErrorMessage = exports.joinApiPath = exports.normalizeApiPath = exports.ApiFunctionRuntimeError = void 0;
|
|
13
|
+
const DBConnection_1 = require("../Database/DBConnection");
|
|
13
14
|
const Request_1 = require("../Router/Request");
|
|
14
15
|
const ApiFunction_1 = require("./ApiFunction");
|
|
15
16
|
const ApiScopesGroup_1 = require("./ApiScopesGroup");
|
|
@@ -206,12 +207,12 @@ function coerceApiFunctionParam(key, value, definition) {
|
|
|
206
207
|
}
|
|
207
208
|
throw new ApiFunctionRuntimeError(`Parameter "${key}" must be a boolean`, 400);
|
|
208
209
|
}
|
|
209
|
-
if (
|
|
210
|
-
const
|
|
211
|
-
if (
|
|
210
|
+
if (["objectid", "databaseid"].includes(type)) {
|
|
211
|
+
const normalizedId = DBConnection_1.DBConnection.getIdAdapter().normalize(value);
|
|
212
|
+
if (normalizedId === null) {
|
|
212
213
|
throw new ApiFunctionRuntimeError(`Parameter "${key}" must be a valid ObjectId`, 400);
|
|
213
214
|
}
|
|
214
|
-
return
|
|
215
|
+
return String(normalizedId);
|
|
215
216
|
}
|
|
216
217
|
if (type === "option") {
|
|
217
218
|
const allowedValues = Array.isArray(definition.options) ? definition.options.map((option) => option.value) : [];
|
|
@@ -264,8 +264,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
264
264
|
return __awaiter(this, void 0, void 0, function* () {
|
|
265
265
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
266
266
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
267
|
-
yield connection
|
|
268
|
-
.db(null)
|
|
267
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
269
268
|
.collection("queue_jobs")
|
|
270
269
|
.updateOne({
|
|
271
270
|
_id: jobId,
|
|
@@ -382,7 +381,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
382
381
|
if (!automation || !automation.jobclass || !automation._execution || !automation._execution.key) {
|
|
383
382
|
continue;
|
|
384
383
|
}
|
|
385
|
-
const existingJob = yield
|
|
384
|
+
const existingJob = yield DBConnection_1.DBConnection.documentStore(connection).collection("queue_jobs").findOne({
|
|
386
385
|
is_automated: true,
|
|
387
386
|
automation_key: automation._execution.key,
|
|
388
387
|
});
|
|
@@ -407,7 +406,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
407
406
|
executions: [],
|
|
408
407
|
worker: this.workerKey,
|
|
409
408
|
};
|
|
410
|
-
yield
|
|
409
|
+
yield DBConnection_1.DBConnection.documentStore(connection).collection("queue_jobs").insertOne(newJob);
|
|
411
410
|
}
|
|
412
411
|
yield this.wait(5000);
|
|
413
412
|
}
|
|
@@ -430,8 +429,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
430
429
|
}
|
|
431
430
|
getNextJobNumber(connection) {
|
|
432
431
|
return __awaiter(this, void 0, void 0, function* () {
|
|
433
|
-
const lastJob = yield connection
|
|
434
|
-
.db(null)
|
|
432
|
+
const lastJob = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
435
433
|
.collection("queue_jobs")
|
|
436
434
|
.findOne({}, { sort: { number: -1 } });
|
|
437
435
|
return lastJob ? (lastJob.number || 0) + 1 : 1;
|
|
@@ -463,8 +461,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
463
461
|
.tz(this.workerConfig.timezone ? this.workerConfig.timezone : "Europe/Berlin")
|
|
464
462
|
.format("YYYYMMDDHHmmss") + StringFunctions_1.StringFunctions.random(24);
|
|
465
463
|
const workerJobclasses = this.getWorkerJobclasses();
|
|
466
|
-
const jobUpdate = yield connection
|
|
467
|
-
.db(null)
|
|
464
|
+
const jobUpdate = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
468
465
|
.collection("queue_jobs")
|
|
469
466
|
.findOneAndUpdate({
|
|
470
467
|
status: "pending",
|
|
@@ -488,11 +485,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
488
485
|
sort: { priority: -1, created_at: 1 },
|
|
489
486
|
returnDocument: "after",
|
|
490
487
|
});
|
|
491
|
-
const job = jobUpdate
|
|
492
|
-
? jobUpdate
|
|
493
|
-
: (jobUpdate === null || jobUpdate === void 0 ? void 0 : jobUpdate.value) && jobUpdate.ok && jobUpdate.value._id && jobUpdate.value.jobclass
|
|
494
|
-
? jobUpdate.value
|
|
495
|
-
: null;
|
|
488
|
+
const job = jobUpdate;
|
|
496
489
|
if (!job || !job.jobclass || !job._id) {
|
|
497
490
|
this.currentJob = null;
|
|
498
491
|
if (job && job._id) {
|
|
@@ -518,8 +511,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
518
511
|
{ key: executionKey, worker: this.workerKey, status: "running", started_at: startedAt },
|
|
519
512
|
...(job.executions && job.executions.length > 0 ? job.executions : []),
|
|
520
513
|
];
|
|
521
|
-
yield connection
|
|
522
|
-
.db(null)
|
|
514
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
523
515
|
.collection("queue_jobs")
|
|
524
516
|
.updateOne({ _id: job._id }, {
|
|
525
517
|
$set: {
|
|
@@ -584,8 +576,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
584
576
|
if (jobNotification) {
|
|
585
577
|
yield NotificationService_1.NotificationService.setChangingStatus(jobNotification, job.status === "pending" ? "pending" : "success");
|
|
586
578
|
}
|
|
587
|
-
yield connection
|
|
588
|
-
.db(null)
|
|
579
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
589
580
|
.collection("queue_jobs")
|
|
590
581
|
.updateOne({ _id: job._id }, {
|
|
591
582
|
$set: {
|
|
@@ -690,8 +681,7 @@ class QueueWorkerCommand extends ConsoleCommand_1.ConsoleCommand {
|
|
|
690
681
|
if (jobInstance) {
|
|
691
682
|
job.executions[0].log = jobInstance.getLog();
|
|
692
683
|
}
|
|
693
|
-
yield connection
|
|
694
|
-
.db(null)
|
|
684
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
695
685
|
.collection("queue_jobs")
|
|
696
686
|
.updateOne({ _id: job._id }, {
|
|
697
687
|
$set: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DocumentDatabase } from "../Database/DatabaseAdapter";
|
|
1
2
|
import { Request } from "../Router/Request";
|
|
2
3
|
export type DataBuilderSchema = {
|
|
3
4
|
version: string;
|
|
@@ -60,8 +61,8 @@ export declare class DataBuilder {
|
|
|
60
61
|
getFieldTypesFrontend(): any;
|
|
61
62
|
getFieldsFrontend(fields: any, payload?: any): Promise<any>;
|
|
62
63
|
getTypeFromRequest(req: any): DataBuilderType;
|
|
63
|
-
validateFields(db:
|
|
64
|
-
handleUnique(db:
|
|
64
|
+
validateFields(db: DocumentDatabase, type: any, fields: any, req: Request, errors?: any, path?: string): Promise<any>;
|
|
65
|
+
handleUnique(db: DocumentDatabase, req: any, key: string, value: any, field: any, type: any): Promise<boolean>;
|
|
65
66
|
typeForFrontend(type: any, req: any): Promise<any>;
|
|
66
67
|
loadType(req: Request): Promise<{
|
|
67
68
|
status: string;
|
|
@@ -73,7 +74,7 @@ export declare class DataBuilder {
|
|
|
73
74
|
[x: number]: any;
|
|
74
75
|
};
|
|
75
76
|
}[]>;
|
|
76
|
-
save(db:
|
|
77
|
+
save(db: DocumentDatabase, req: any): Promise<{
|
|
77
78
|
status: string;
|
|
78
79
|
errors: any;
|
|
79
80
|
data?: undefined;
|
|
@@ -82,7 +83,7 @@ export declare class DataBuilder {
|
|
|
82
83
|
data: any;
|
|
83
84
|
errors?: undefined;
|
|
84
85
|
}>;
|
|
85
|
-
delete(db:
|
|
86
|
+
delete(db: DocumentDatabase, req: any): Promise<{
|
|
86
87
|
status: string;
|
|
87
88
|
data: {
|
|
88
89
|
_id: any;
|
|
@@ -91,11 +92,11 @@ export declare class DataBuilder {
|
|
|
91
92
|
}>;
|
|
92
93
|
getField(req: Request, type: DataBuilderType, path: string): Promise<any>;
|
|
93
94
|
removeArrayIndicators(str: string): string;
|
|
94
|
-
details(db:
|
|
95
|
+
details(db: DocumentDatabase, req: any): Promise<{
|
|
95
96
|
status: string;
|
|
96
97
|
data: any;
|
|
97
98
|
}>;
|
|
98
|
-
detailsNewData(db:
|
|
99
|
+
detailsNewData(db: DocumentDatabase, req: any): Promise<{
|
|
99
100
|
status: string;
|
|
100
101
|
message: string;
|
|
101
102
|
data?: undefined;
|
|
@@ -293,8 +293,8 @@ class DataBuilder {
|
|
|
293
293
|
else {
|
|
294
294
|
let elementVal = null;
|
|
295
295
|
if (fields[key].type === "ObjectId") {
|
|
296
|
-
if (value &&
|
|
297
|
-
elementVal =
|
|
296
|
+
if (value !== undefined && value !== null && value !== "") {
|
|
297
|
+
elementVal = yield Model_1.Model.objectId(value);
|
|
298
298
|
}
|
|
299
299
|
else {
|
|
300
300
|
elementVal = yield Model_1.Model.objectId();
|
|
@@ -605,6 +605,8 @@ class DataBuilder {
|
|
|
605
605
|
throw new Error("Missing schema fields ...");
|
|
606
606
|
}
|
|
607
607
|
const collection = type.schema && type.schema.collection ? type.schema.collection : undefined;
|
|
608
|
+
if (!collection)
|
|
609
|
+
throw new Error("Missing schema collection ...");
|
|
608
610
|
let element = null;
|
|
609
611
|
try {
|
|
610
612
|
element = yield db
|
|
@@ -25,16 +25,16 @@ class DataBuilderController extends Controller_1.Controller {
|
|
|
25
25
|
return res.send(yield this.builder.apiAutoComplete(req));
|
|
26
26
|
}
|
|
27
27
|
else if (req.body.__builder_rest_api === "details") {
|
|
28
|
-
return res.send(yield this.builder.details(
|
|
28
|
+
return res.send(yield this.builder.details(DBConnection_1.DBConnection.documentStore(db), req));
|
|
29
29
|
}
|
|
30
30
|
else if (req.body.__builder_rest_api === "details-newdata") {
|
|
31
|
-
return res.send(yield this.builder.detailsNewData(
|
|
31
|
+
return res.send(yield this.builder.detailsNewData(DBConnection_1.DBConnection.documentStore(db), req));
|
|
32
32
|
}
|
|
33
33
|
else if (req.body.__builder_rest_api === "save") {
|
|
34
|
-
return res.send(yield this.builder.save(
|
|
34
|
+
return res.send(yield this.builder.save(DBConnection_1.DBConnection.documentStore(db), req));
|
|
35
35
|
}
|
|
36
36
|
else if (req.body.__builder_rest_api === "delete") {
|
|
37
|
-
return res.send(yield this.builder.delete(
|
|
37
|
+
return res.send(yield this.builder.delete(DBConnection_1.DBConnection.documentStore(db), req));
|
|
38
38
|
}
|
|
39
39
|
else if (req.body.__builder_rest_api === "type") {
|
|
40
40
|
return res.send(yield this.builder.loadType(req));
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { DatabaseIdAdapter, DocumentDatabase } from "./DatabaseAdapter";
|
|
1
2
|
import { Model } from "./Model";
|
|
2
3
|
import { QueryBuilder } from "./QueryBuilder";
|
|
3
4
|
export declare class BaseDBDriver {
|
|
4
5
|
config?: object;
|
|
6
|
+
get idAdapter(): DatabaseIdAdapter;
|
|
7
|
+
documentStore(client: any): DocumentDatabase;
|
|
8
|
+
objectId(value?: unknown): Promise<import("./DatabaseAdapter").DatabaseId>;
|
|
5
9
|
setConfig(config: object): void;
|
|
6
10
|
connect(): Promise<void>;
|
|
7
11
|
close(client: any): Promise<void>;
|
|
@@ -11,6 +11,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.BaseDBDriver = void 0;
|
|
13
13
|
class BaseDBDriver {
|
|
14
|
+
get idAdapter() {
|
|
15
|
+
throw new Error("This database driver does not implement ID handling.");
|
|
16
|
+
}
|
|
17
|
+
documentStore(client) {
|
|
18
|
+
throw new Error("This database driver does not support document queries (required for Datatables, DataBuilder, queues and notifications).");
|
|
19
|
+
}
|
|
20
|
+
objectId(value) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
return this.idAdapter.create(value);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
14
25
|
setConfig(config) {
|
|
15
26
|
this.config = config;
|
|
16
27
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DatabaseIdAdapter, DocumentDatabase } from "./DatabaseAdapter";
|
|
1
2
|
import { QueryBuilder } from "./QueryBuilder";
|
|
2
3
|
type ObjectIDType = {
|
|
3
4
|
noExceptions?: Boolean;
|
|
@@ -6,8 +7,12 @@ declare class DBConnectionFacade {
|
|
|
6
7
|
connections: {
|
|
7
8
|
[key: string]: any;
|
|
8
9
|
};
|
|
9
|
-
getConnectionConfig(connection
|
|
10
|
-
getConnectionDriver(connection
|
|
10
|
+
getConnectionConfig(connection?: string): any;
|
|
11
|
+
getConnectionDriver(connection?: string): any;
|
|
12
|
+
/** Resolves ID handling without opening a connection. Core import stays side-effect free. */
|
|
13
|
+
getIdAdapter(connectionName?: string): DatabaseIdAdapter;
|
|
14
|
+
documentStore(connection: any): DocumentDatabase;
|
|
15
|
+
getDocumentStore(connectionName?: string): Promise<DocumentDatabase>;
|
|
11
16
|
getConnection(connectionName?: string): Promise<any>;
|
|
12
17
|
runQuery(query: QueryBuilder, options?: {
|
|
13
18
|
[name: string]: any;
|
|
@@ -33,13 +33,37 @@ class DBConnectionFacade {
|
|
|
33
33
|
getConnectionDriver(connection) {
|
|
34
34
|
const config = this.getConnectionConfig(connection);
|
|
35
35
|
if (!config || !config["driver"]) {
|
|
36
|
-
|
|
36
|
+
throw new Error("No database driver configured.");
|
|
37
37
|
}
|
|
38
38
|
const driverClass = DBDrivers_1.DBDrivers.get(config["driver"]);
|
|
39
|
+
if (!driverClass)
|
|
40
|
+
throw new Error(`Database driver "${config["driver"]}" is not registered. Install and register a driver before using database features.`);
|
|
39
41
|
const driver = new driverClass();
|
|
40
42
|
driver.setConfig(config);
|
|
41
43
|
return driver;
|
|
42
44
|
}
|
|
45
|
+
/** Resolves ID handling without opening a connection. Core import stays side-effect free. */
|
|
46
|
+
getIdAdapter(connectionName) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
const name = connectionName || ((_a = Config_1.Config.get("database")) === null || _a === void 0 ? void 0 : _a.defaultConnection);
|
|
49
|
+
const driver = (name && ((_b = this.connections[name]) === null || _b === void 0 ? void 0 : _b.driver)) || this.getConnectionDriver(connectionName);
|
|
50
|
+
const adapter = driver.idAdapter;
|
|
51
|
+
if (!adapter)
|
|
52
|
+
throw new Error("This database driver does not implement ID handling.");
|
|
53
|
+
return adapter;
|
|
54
|
+
}
|
|
55
|
+
documentStore(connection) {
|
|
56
|
+
var _a;
|
|
57
|
+
if (typeof ((_a = connection === null || connection === void 0 ? void 0 : connection.driver) === null || _a === void 0 ? void 0 : _a.documentStore) !== "function") {
|
|
58
|
+
throw new Error("The configured database driver does not support document queries. Update the driver to use this feature.");
|
|
59
|
+
}
|
|
60
|
+
return connection.driver.documentStore(connection.client);
|
|
61
|
+
}
|
|
62
|
+
getDocumentStore(connectionName) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
return this.documentStore(yield this.getConnection(connectionName));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
43
67
|
getConnection(connectionName) {
|
|
44
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
69
|
const dbconfig = Config_1.Config.get("database");
|
|
@@ -50,7 +74,7 @@ class DBConnectionFacade {
|
|
|
50
74
|
connectionName = dbconfig.defaultConnection;
|
|
51
75
|
}
|
|
52
76
|
if (!connectionName) {
|
|
53
|
-
|
|
77
|
+
throw new Error("No default database connection configured.");
|
|
54
78
|
}
|
|
55
79
|
if (this.connections[connectionName] && this.connections[connectionName].driver) {
|
|
56
80
|
// Use cached connection
|
|
@@ -94,20 +118,17 @@ class DBConnectionFacade {
|
|
|
94
118
|
return connection.driver;
|
|
95
119
|
});
|
|
96
120
|
}
|
|
121
|
+
// Preserve the existing driver-defined return type for Model.objectId consumers.
|
|
97
122
|
objectId(val, connectionName, options) {
|
|
98
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.error(e);
|
|
106
|
-
}
|
|
124
|
+
try {
|
|
125
|
+
return this.getIdAdapter(connectionName).create(val);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (!(options === null || options === void 0 ? void 0 : options.noExceptions))
|
|
129
|
+
throw error;
|
|
107
130
|
return null;
|
|
108
131
|
}
|
|
109
|
-
const connection = yield this.getConnection(connectionName);
|
|
110
|
-
return yield connection.driver.objectId(val);
|
|
111
132
|
});
|
|
112
133
|
}
|
|
113
134
|
mapDataToModel(model, data) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** An ID is owned by the selected driver, not by the core package. */
|
|
2
|
+
export type DatabaseId = string | number | {
|
|
3
|
+
toString(): string;
|
|
4
|
+
};
|
|
5
|
+
export interface DatabaseIdAdapter {
|
|
6
|
+
create(value?: unknown): DatabaseId;
|
|
7
|
+
normalize(value: unknown): DatabaseId | null;
|
|
8
|
+
isValid(value: unknown): boolean;
|
|
9
|
+
equals(left: unknown, right: unknown): boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface DocumentCursor {
|
|
12
|
+
toArray(): Promise<any[]>;
|
|
13
|
+
sort(sort: any): DocumentCursor;
|
|
14
|
+
skip(count: number): DocumentCursor;
|
|
15
|
+
limit(count: number): DocumentCursor;
|
|
16
|
+
}
|
|
17
|
+
/** Optional document-query capability. Filters, updates and aggregation stages use
|
|
18
|
+
* the framework's document query vocabulary. A driver implements or translates it;
|
|
19
|
+
* unsupported drivers must reject the capability rather than emulate atomicity. */
|
|
20
|
+
export interface DocumentCollection {
|
|
21
|
+
find(filter?: any, options?: any): DocumentCursor;
|
|
22
|
+
findOne(filter: any, options?: any): Promise<any | null>;
|
|
23
|
+
aggregate(stages: any[], options?: any): DocumentCursor;
|
|
24
|
+
countDocuments(filter?: any, options?: any): Promise<number>;
|
|
25
|
+
insertOne(document: any, options?: any): Promise<any>;
|
|
26
|
+
insertMany(documents: any[], options?: any): Promise<any>;
|
|
27
|
+
updateOne(filter: any, update: any, options?: any): Promise<any>;
|
|
28
|
+
updateMany(filter: any, update: any, options?: any): Promise<any>;
|
|
29
|
+
replaceOne(filter: any, replacement: any, options?: any): Promise<any>;
|
|
30
|
+
deleteOne(filter: any, options?: any): Promise<any>;
|
|
31
|
+
deleteMany(filter: any, options?: any): Promise<any>;
|
|
32
|
+
/** Atomically selects and updates ONE document; returns the document or null.
|
|
33
|
+
* Never return a driver-specific result wrapper. Queue leases depend on this. */
|
|
34
|
+
findOneAndUpdate(filter: any, update: any, options?: {
|
|
35
|
+
sort?: any;
|
|
36
|
+
upsert?: boolean;
|
|
37
|
+
returnDocument?: "before" | "after";
|
|
38
|
+
}): Promise<any | null>;
|
|
39
|
+
}
|
|
40
|
+
export interface DocumentDatabase {
|
|
41
|
+
collection(name: string): DocumentCollection;
|
|
42
|
+
}
|
|
@@ -67,7 +67,7 @@ export declare class Datatable {
|
|
|
67
67
|
max_entries: any;
|
|
68
68
|
total_pages: number;
|
|
69
69
|
per_page: number;
|
|
70
|
-
entries: any;
|
|
70
|
+
entries: any[];
|
|
71
71
|
sums: any;
|
|
72
72
|
}>;
|
|
73
73
|
stats(req: Request): Promise<Array<{
|
|
@@ -75,7 +75,7 @@ export declare class Datatable {
|
|
|
75
75
|
type: string;
|
|
76
76
|
value: any;
|
|
77
77
|
}>>;
|
|
78
|
-
getTotalData(req: Request): Promise<any>;
|
|
78
|
+
getTotalData(req: Request): Promise<any[]>;
|
|
79
79
|
getFilter(req: Request): Promise<any>;
|
|
80
80
|
getColumns(req: Request): Promise<any>;
|
|
81
81
|
getOnPressLink(req: Request): Promise<any>;
|
|
@@ -25,7 +25,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.Datatable = void 0;
|
|
27
27
|
const moment_1 = __importDefault(require("moment"));
|
|
28
|
-
const mongodb_1 = require("mongodb");
|
|
29
28
|
const DBConnection_1 = require("../Database/DBConnection");
|
|
30
29
|
const NumericFunctions_1 = require("../Functions/NumericFunctions");
|
|
31
30
|
class Datatable {
|
|
@@ -115,15 +114,9 @@ class Datatable {
|
|
|
115
114
|
}
|
|
116
115
|
let value = rawValue;
|
|
117
116
|
if (config.value === "_id") {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
else if (typeof rawValue === "string" && mongodb_1.ObjectId.isValid(rawValue)) {
|
|
122
|
-
value = new mongodb_1.ObjectId(rawValue);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
117
|
+
value = DBConnection_1.DBConnection.getIdAdapter().normalize(rawValue);
|
|
118
|
+
if (value === null)
|
|
125
119
|
return null;
|
|
126
|
-
}
|
|
127
120
|
}
|
|
128
121
|
const normalizeStages = (stages) => (stages !== null && stages !== void 0 ? stages : []).map((stage) => {
|
|
129
122
|
if (!stage || typeof stage !== "object" || !Object.prototype.hasOwnProperty.call(stage, "skipStats")) {
|
|
@@ -139,8 +132,7 @@ class Datatable {
|
|
|
139
132
|
{ $limit: 1 },
|
|
140
133
|
];
|
|
141
134
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
142
|
-
const results = yield connection
|
|
143
|
-
.db(null)
|
|
135
|
+
const results = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
144
136
|
.collection(yield this.getCollection(req))
|
|
145
137
|
.aggregate(aggregation, {
|
|
146
138
|
collation: {
|
|
@@ -310,8 +302,7 @@ class Datatable {
|
|
|
310
302
|
log("[DATATABLE_AGGREGATION" + (req.body._table ? "-" + req.body._table : "") + "]", aggr);
|
|
311
303
|
}
|
|
312
304
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
313
|
-
const results = yield connection
|
|
314
|
-
.db(null)
|
|
305
|
+
const results = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
315
306
|
.collection(yield this.getCollection(req))
|
|
316
307
|
.aggregate(aggr, {
|
|
317
308
|
collation: {
|
|
@@ -334,8 +325,7 @@ class Datatable {
|
|
|
334
325
|
}
|
|
335
326
|
}
|
|
336
327
|
}
|
|
337
|
-
const stats = yield connection
|
|
338
|
-
.db(null)
|
|
328
|
+
const stats = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
339
329
|
.collection(yield this.getCollection(req))
|
|
340
330
|
.aggregate([...(aggregationStats ? aggregationStats : []), statsGroup])
|
|
341
331
|
.toArray();
|
|
@@ -417,8 +407,7 @@ class Datatable {
|
|
|
417
407
|
}
|
|
418
408
|
}
|
|
419
409
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
420
|
-
return yield connection
|
|
421
|
-
.db(null)
|
|
410
|
+
return yield DBConnection_1.DBConnection.documentStore(connection)
|
|
422
411
|
.collection(yield this.getCollection(req))
|
|
423
412
|
.aggregate([...(aggregation ? aggregation : [])])
|
|
424
413
|
.toArray();
|
|
@@ -15,7 +15,7 @@ const paginationList = (options, aggregation, aggregationOptional) => __awaiter(
|
|
|
15
15
|
const page = options.page && parseInt(options.page) > 0 ? parseInt(options.page) : 0;
|
|
16
16
|
const perPage = options.perPage && parseInt(options.perPage) > 0 ? parseInt(options.perPage) : 50;
|
|
17
17
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
18
|
-
const collection =
|
|
18
|
+
const collection = DBConnection_1.DBConnection.documentStore(connection).collection(options.collection);
|
|
19
19
|
const promises = [];
|
|
20
20
|
let total = 0;
|
|
21
21
|
promises.push(new Promise((resolve) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DatabaseId } from "../Database/DatabaseAdapter";
|
|
2
2
|
import { Model } from "../Database/Model";
|
|
3
3
|
import type { NotificationChangingStatus, NotificationModes, NotificationReadStatus, NotificationViewStatus } from "./NotificationService";
|
|
4
4
|
export declare class Notification extends Model {
|
|
5
5
|
target?: string;
|
|
6
|
-
target_id?:
|
|
6
|
+
target_id?: DatabaseId;
|
|
7
7
|
targetModel?: any;
|
|
8
8
|
key?: string;
|
|
9
9
|
mode?: NotificationModes;
|
|
10
10
|
changing_status?: NotificationChangingStatus;
|
|
11
11
|
changing_error?: string | null;
|
|
12
|
-
_queue_job?:
|
|
13
|
-
_files?:
|
|
12
|
+
_queue_job?: DatabaseId;
|
|
13
|
+
_files?: DatabaseId[];
|
|
14
14
|
read_status?: NotificationReadStatus;
|
|
15
15
|
read_at?: Date | null;
|
|
16
16
|
view_status?: NotificationViewStatus;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DatabaseId } from "../Database/DatabaseAdapter";
|
|
2
2
|
import { Request } from "../Router/Request";
|
|
3
3
|
import { Notification } from "./Notification";
|
|
4
4
|
export type NotificationModes = "fixed" | "changing";
|
|
@@ -13,7 +13,7 @@ export type NotificationParameterDefinition = {
|
|
|
13
13
|
};
|
|
14
14
|
export type NotificationTargetContext = {
|
|
15
15
|
target: string;
|
|
16
|
-
target_id:
|
|
16
|
+
target_id: DatabaseId;
|
|
17
17
|
targetModel?: any;
|
|
18
18
|
request?: Request;
|
|
19
19
|
};
|
|
@@ -123,8 +123,8 @@ declare class NotificationServiceFacade {
|
|
|
123
123
|
set registy(registry: {
|
|
124
124
|
[key: string]: NotificationDefinition;
|
|
125
125
|
});
|
|
126
|
-
private getObjectIdString;
|
|
127
126
|
private normalizeObjectId;
|
|
127
|
+
private sameId;
|
|
128
128
|
private getNotificationReferenceId;
|
|
129
129
|
init(): void;
|
|
130
130
|
registerType(type: NotificationDefinition): this;
|
|
@@ -158,17 +158,17 @@ declare class NotificationServiceFacade {
|
|
|
158
158
|
private getLoadAggregation;
|
|
159
159
|
private enrichNotification;
|
|
160
160
|
create(typeKey: string, payload: NotificationPayload, options: NotificationOptions): Promise<Notification | null>;
|
|
161
|
-
getNotification(notificationRef: Notification |
|
|
162
|
-
setQueueJobFailureStatus(notificationRef:
|
|
163
|
-
markAsRead(
|
|
164
|
-
markAsViewed(
|
|
161
|
+
getNotification(notificationRef: Notification | DatabaseId | null): Promise<Notification>;
|
|
162
|
+
setQueueJobFailureStatus(notificationRef: DatabaseId | null, error?: string | null): Promise<boolean>;
|
|
163
|
+
markAsRead(notificationRef: Notification | DatabaseId | null): Promise<Notification>;
|
|
164
|
+
markAsViewed(notificationRef: Notification | DatabaseId | null): Promise<Notification>;
|
|
165
165
|
markAllAsRead(context: NotificationTargetContext): Promise<void>;
|
|
166
166
|
markAllAsViewed(context: NotificationTargetContext): Promise<void>;
|
|
167
|
-
getNotificationForTarget(notificationRef: Notification |
|
|
167
|
+
getNotificationForTarget(notificationRef: Notification | DatabaseId | null, context: NotificationTargetContext): Promise<Notification | null>;
|
|
168
168
|
private countByStatus;
|
|
169
169
|
getUnreadCount(context: NotificationTargetContext): Promise<number>;
|
|
170
170
|
getUnviewedCount(context: NotificationTargetContext): Promise<number>;
|
|
171
|
-
updateNotification(
|
|
171
|
+
updateNotification(notificationRef: Notification | DatabaseId | null, updateData: {
|
|
172
172
|
payload?: NotificationPayload;
|
|
173
173
|
show_at?: Date | null;
|
|
174
174
|
read_status?: NotificationReadStatus;
|
|
@@ -176,10 +176,10 @@ declare class NotificationServiceFacade {
|
|
|
176
176
|
view_status?: NotificationViewStatus;
|
|
177
177
|
viewed_at?: Date | null;
|
|
178
178
|
}): Promise<Notification>;
|
|
179
|
-
setChangingStatus(
|
|
179
|
+
setChangingStatus(notificationRef: Notification | DatabaseId | null, status: NotificationChangingStatus, error?: string | null): Promise<Notification>;
|
|
180
180
|
loadNotifications(options: {
|
|
181
181
|
target: string;
|
|
182
|
-
target_id:
|
|
182
|
+
target_id: DatabaseId;
|
|
183
183
|
targetModel?: any;
|
|
184
184
|
offset?: number;
|
|
185
185
|
limit?: number;
|
|
@@ -21,7 +21,6 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.NotificationService = exports.NotificationTargetValidationError = exports.NotificationPayloadValidationError = void 0;
|
|
24
|
-
const mongodb_1 = require("mongodb");
|
|
25
24
|
const Notification_1 = require("./Notification");
|
|
26
25
|
const Config_1 = require("../Config");
|
|
27
26
|
const DBConnection_1 = require("../Database/DBConnection");
|
|
@@ -56,22 +55,14 @@ class NotificationServiceFacade {
|
|
|
56
55
|
set registy(registry) {
|
|
57
56
|
this.registry = registry;
|
|
58
57
|
}
|
|
59
|
-
getObjectIdString(value) {
|
|
60
|
-
const objectIdString = typeof value === "string"
|
|
61
|
-
? value
|
|
62
|
-
: value && typeof value.toString === "function"
|
|
63
|
-
? value.toString()
|
|
64
|
-
: null;
|
|
65
|
-
return objectIdString && objectIdString.length === 24 && mongodb_1.ObjectId.isValid(objectIdString)
|
|
66
|
-
? objectIdString
|
|
67
|
-
: null;
|
|
68
|
-
}
|
|
69
58
|
normalizeObjectId(value) {
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
return DBConnection_1.DBConnection.getIdAdapter(new Notification_1.Notification().__connection).normalize(value);
|
|
60
|
+
}
|
|
61
|
+
sameId(left, right) {
|
|
62
|
+
return DBConnection_1.DBConnection.getIdAdapter(new Notification_1.Notification().__connection).equals(left, right);
|
|
72
63
|
}
|
|
73
64
|
getNotificationReferenceId(notificationRef) {
|
|
74
|
-
return this.
|
|
65
|
+
return this.normalizeObjectId(notificationRef);
|
|
75
66
|
}
|
|
76
67
|
init() {
|
|
77
68
|
this.registry = {};
|
|
@@ -176,7 +167,7 @@ class NotificationServiceFacade {
|
|
|
176
167
|
}
|
|
177
168
|
normalizeTargetId(targetId) {
|
|
178
169
|
const normalized = this.normalizeObjectId(targetId);
|
|
179
|
-
if (
|
|
170
|
+
if (normalized === null) {
|
|
180
171
|
throw new NotificationTargetValidationError("Invalid notification target_id.");
|
|
181
172
|
}
|
|
182
173
|
return normalized;
|
|
@@ -189,17 +180,17 @@ class NotificationServiceFacade {
|
|
|
189
180
|
if (!this.getTargetDefinition(target)) {
|
|
190
181
|
throw new NotificationTargetValidationError(`Unknown notification target '${target}'.`);
|
|
191
182
|
}
|
|
192
|
-
if (
|
|
183
|
+
if (context.target_id === null || context.target_id === undefined || context.target_id === "") {
|
|
193
184
|
throw new NotificationTargetValidationError("Notification target_id required.");
|
|
194
185
|
}
|
|
195
186
|
return Object.assign(Object.assign({}, context), { target, target_id: this.normalizeTargetId(context.target_id) });
|
|
196
187
|
}
|
|
197
188
|
resolveTarget(context) {
|
|
198
|
-
var _a
|
|
189
|
+
var _a;
|
|
199
190
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
191
|
const normalized = this.normalizeTargetContext(context);
|
|
201
192
|
if (normalized.targetModel) {
|
|
202
|
-
return (
|
|
193
|
+
return this.sameId(this.getModelId(normalized.targetModel), normalized.target_id) ? normalized : null;
|
|
203
194
|
}
|
|
204
195
|
const definition = this.getTargetDefinition(normalized.target);
|
|
205
196
|
let targetModel = null;
|
|
@@ -207,19 +198,18 @@ class NotificationServiceFacade {
|
|
|
207
198
|
targetModel = yield definition.resolve(normalized);
|
|
208
199
|
}
|
|
209
200
|
else if (normalized.target === "user" &&
|
|
210
|
-
((
|
|
211
|
-
(
|
|
201
|
+
((_a = normalized.request) === null || _a === void 0 ? void 0 : _a.user) &&
|
|
202
|
+
this.sameId(this.getModelId(normalized.request.user), normalized.target_id)) {
|
|
212
203
|
targetModel = normalized.request.user;
|
|
213
204
|
}
|
|
214
205
|
else if (definition.collection) {
|
|
215
206
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
216
|
-
targetModel = yield connection
|
|
217
|
-
.db(null)
|
|
207
|
+
targetModel = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
218
208
|
.collection(definition.collection)
|
|
219
209
|
.findOne({ _id: normalized.target_id });
|
|
220
210
|
}
|
|
221
211
|
const modelId = this.getModelId(targetModel);
|
|
222
|
-
return (modelId
|
|
212
|
+
return this.sameId(modelId, normalized.target_id) ? Object.assign(Object.assign({}, normalized), { targetModel }) : null;
|
|
223
213
|
});
|
|
224
214
|
}
|
|
225
215
|
authorizeTarget(context) {
|
|
@@ -234,7 +224,7 @@ class NotificationServiceFacade {
|
|
|
234
224
|
if (!resolved.request)
|
|
235
225
|
return resolved;
|
|
236
226
|
const requestUserId = this.getModelId(resolved.request.user);
|
|
237
|
-
return (requestUserId
|
|
227
|
+
return this.sameId(requestUserId, resolved.target_id) ? resolved : null;
|
|
238
228
|
});
|
|
239
229
|
}
|
|
240
230
|
attachTargetModel(notification, targetModel) {
|
|
@@ -358,8 +348,7 @@ class NotificationServiceFacade {
|
|
|
358
348
|
}
|
|
359
349
|
else if (((_a = this.getTargetDefinition(resolved.target)) === null || _a === void 0 ? void 0 : _a.collection) && owner._id) {
|
|
360
350
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
361
|
-
yield connection
|
|
362
|
-
.db(null)
|
|
351
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
363
352
|
.collection(this.getTargetDefinition(resolved.target).collection)
|
|
364
353
|
.updateOne({ _id: owner._id }, { $set: { [preferencesField]: preferences } });
|
|
365
354
|
}
|
|
@@ -633,7 +622,7 @@ class NotificationServiceFacade {
|
|
|
633
622
|
return notificationRef;
|
|
634
623
|
}
|
|
635
624
|
const notificationId = this.getNotificationReferenceId(notificationRef);
|
|
636
|
-
if (notificationId
|
|
625
|
+
if (notificationId !== null) {
|
|
637
626
|
const loadNotification = yield Notification_1.Notification.where("_id", "=", yield Notification_1.Notification.objectId(notificationId)).first();
|
|
638
627
|
if (loadNotification) {
|
|
639
628
|
return loadNotification;
|
|
@@ -645,13 +634,12 @@ class NotificationServiceFacade {
|
|
|
645
634
|
setQueueJobFailureStatus(notificationRef, error) {
|
|
646
635
|
return __awaiter(this, void 0, void 0, function* () {
|
|
647
636
|
const notificationId = this.getNotificationReferenceId(notificationRef);
|
|
648
|
-
if (
|
|
637
|
+
if (notificationId === null) {
|
|
649
638
|
throw new Error("Invalid notification reference provided: " + (notificationRef === null || notificationRef === void 0 ? void 0 : notificationRef.toString()));
|
|
650
639
|
}
|
|
651
640
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
652
641
|
const completedAt = new Date();
|
|
653
|
-
const result = yield connection
|
|
654
|
-
.db(null)
|
|
642
|
+
const result = yield DBConnection_1.DBConnection.documentStore(connection)
|
|
655
643
|
.collection(new Notification_1.Notification().__table)
|
|
656
644
|
.updateOne({ _id: yield Notification_1.Notification.objectId(notificationId) }, {
|
|
657
645
|
$set: {
|
|
@@ -668,9 +656,9 @@ class NotificationServiceFacade {
|
|
|
668
656
|
return result.matchedCount > 0;
|
|
669
657
|
});
|
|
670
658
|
}
|
|
671
|
-
markAsRead(
|
|
659
|
+
markAsRead(notificationRef) {
|
|
672
660
|
return __awaiter(this, void 0, void 0, function* () {
|
|
673
|
-
notification = yield this.getNotification(
|
|
661
|
+
const notification = yield this.getNotification(notificationRef);
|
|
674
662
|
if (notification.read_status === "read" && notification.view_status === "viewed") {
|
|
675
663
|
return notification;
|
|
676
664
|
}
|
|
@@ -690,9 +678,9 @@ class NotificationServiceFacade {
|
|
|
690
678
|
return notification;
|
|
691
679
|
});
|
|
692
680
|
}
|
|
693
|
-
markAsViewed(
|
|
681
|
+
markAsViewed(notificationRef) {
|
|
694
682
|
return __awaiter(this, void 0, void 0, function* () {
|
|
695
|
-
notification = yield this.getNotification(
|
|
683
|
+
const notification = yield this.getNotification(notificationRef);
|
|
696
684
|
if (notification.view_status === "viewed") {
|
|
697
685
|
return notification;
|
|
698
686
|
}
|
|
@@ -711,8 +699,7 @@ class NotificationServiceFacade {
|
|
|
711
699
|
return __awaiter(this, void 0, void 0, function* () {
|
|
712
700
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
713
701
|
const now = new Date();
|
|
714
|
-
yield connection
|
|
715
|
-
.db(null)
|
|
702
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
716
703
|
.collection(new Notification_1.Notification().__table)
|
|
717
704
|
.updateMany(Object.assign(Object.assign({}, (yield this.getLoadMatch(context))), { $or: [{ read_status: "unread" }, { view_status: "unviewed" }] }), [
|
|
718
705
|
{
|
|
@@ -729,8 +716,7 @@ class NotificationServiceFacade {
|
|
|
729
716
|
markAllAsViewed(context) {
|
|
730
717
|
return __awaiter(this, void 0, void 0, function* () {
|
|
731
718
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
732
|
-
yield connection
|
|
733
|
-
.db(null)
|
|
719
|
+
yield DBConnection_1.DBConnection.documentStore(connection)
|
|
734
720
|
.collection(new Notification_1.Notification().__table)
|
|
735
721
|
.updateMany(Object.assign(Object.assign({}, (yield this.getLoadMatch(context))), { view_status: "unviewed" }), {
|
|
736
722
|
$set: {
|
|
@@ -744,7 +730,7 @@ class NotificationServiceFacade {
|
|
|
744
730
|
return __awaiter(this, void 0, void 0, function* () {
|
|
745
731
|
const notificationId = notificationRef instanceof Notification_1.Notification ? notificationRef._id : notificationRef;
|
|
746
732
|
const objectId = this.normalizeObjectId(notificationId);
|
|
747
|
-
if (
|
|
733
|
+
if (objectId === null)
|
|
748
734
|
return null;
|
|
749
735
|
const notifications = yield Notification_1.Notification.aggregate([
|
|
750
736
|
{
|
|
@@ -782,9 +768,9 @@ class NotificationServiceFacade {
|
|
|
782
768
|
return yield this.countByStatus(context, { view_status: "unviewed" });
|
|
783
769
|
});
|
|
784
770
|
}
|
|
785
|
-
updateNotification(
|
|
771
|
+
updateNotification(notificationRef, updateData) {
|
|
786
772
|
return __awaiter(this, void 0, void 0, function* () {
|
|
787
|
-
notification = yield this.getNotification(
|
|
773
|
+
const notification = yield this.getNotification(notificationRef);
|
|
788
774
|
if (updateData.payload) {
|
|
789
775
|
notification.payload = Object.assign(Object.assign({}, notification.payload), updateData.payload);
|
|
790
776
|
}
|
|
@@ -807,10 +793,10 @@ class NotificationServiceFacade {
|
|
|
807
793
|
return notification;
|
|
808
794
|
});
|
|
809
795
|
}
|
|
810
|
-
setChangingStatus(
|
|
796
|
+
setChangingStatus(notificationRef, status, error) {
|
|
811
797
|
var _a;
|
|
812
798
|
return __awaiter(this, void 0, void 0, function* () {
|
|
813
|
-
notification = yield this.getNotification(
|
|
799
|
+
const notification = yield this.getNotification(notificationRef);
|
|
814
800
|
if (notification.mode !== "changing") {
|
|
815
801
|
throw new Error(`Notification '${(_a = notification._id) === null || _a === void 0 ? void 0 : _a.toString()}' is not in changing mode.`);
|
|
816
802
|
}
|
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.NotificationsOutputChannelsJob = void 0;
|
|
13
|
-
const
|
|
13
|
+
const node_crypto_1 = require("node:crypto");
|
|
14
14
|
const Config_1 = require("../Config");
|
|
15
15
|
const DBConnection_1 = require("../Database/DBConnection");
|
|
16
16
|
const BaseQueueJob_1 = require("../Queue/BaseQueueJob");
|
|
@@ -131,7 +131,7 @@ class NotificationsOutputChannelsJob extends BaseQueueJob_1.BaseQueueJob {
|
|
|
131
131
|
return __awaiter(this, void 0, void 0, function* () {
|
|
132
132
|
const now = new Date();
|
|
133
133
|
const staleClaimBefore = new Date(now.getTime() - claimTimeoutMinutes * 60 * 1000);
|
|
134
|
-
const claimToken =
|
|
134
|
+
const claimToken = (0, node_crypto_1.randomUUID)();
|
|
135
135
|
const claimResult = yield collection.findOneAndUpdate({
|
|
136
136
|
key: { $ne: null },
|
|
137
137
|
show_at: { $lte: eligibleBefore },
|
|
@@ -164,11 +164,7 @@ class NotificationsOutputChannelsJob extends BaseQueueJob_1.BaseQueueJob {
|
|
|
164
164
|
sort: { show_at: 1, created_at: 1 },
|
|
165
165
|
returnDocument: "after",
|
|
166
166
|
});
|
|
167
|
-
const notificationData = claimResult
|
|
168
|
-
? claimResult
|
|
169
|
-
: (claimResult === null || claimResult === void 0 ? void 0 : claimResult.value) && claimResult.value._id
|
|
170
|
-
? claimResult.value
|
|
171
|
-
: null;
|
|
167
|
+
const notificationData = claimResult;
|
|
172
168
|
if (!notificationData)
|
|
173
169
|
return null;
|
|
174
170
|
return DBConnection_1.DBConnection.mapDataToModel(Notification_1.Notification, notificationData);
|
|
@@ -368,7 +364,7 @@ class NotificationsOutputChannelsJob extends BaseQueueJob_1.BaseQueueJob {
|
|
|
368
364
|
const claimTimeoutMinutes = this.positiveNumber(deliveryConfig.claim_timeout_minutes, 30);
|
|
369
365
|
const delaySeconds = this.nonNegativeNumber(deliveryConfig.delay_seconds, 0);
|
|
370
366
|
const connection = yield DBConnection_1.DBConnection.getConnection();
|
|
371
|
-
const collection =
|
|
367
|
+
const collection = DBConnection_1.DBConnection.documentStore(connection).collection(new Notification_1.Notification().__table);
|
|
372
368
|
const maxNotifications = this.attempts * this.perAttempt;
|
|
373
369
|
const eligibleBefore = new Date(Date.now() - delaySeconds * 1000);
|
|
374
370
|
yield this.skipViewedNotifications(collection, eligibleBefore, claimTimeoutMinutes);
|
package/dist/Queue/Queue.js
CHANGED
|
@@ -20,7 +20,7 @@ const QueueJobsRegisty_1 = require("./QueueJobsRegisty");
|
|
|
20
20
|
* Uses the same queue_jobs records and BaseQueueJob handlers as console workers. */
|
|
21
21
|
class Queue {
|
|
22
22
|
static collection() {
|
|
23
|
-
return __awaiter(this, void 0, void 0, function* () { return (yield DBConnection_1.DBConnection.
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () { return (yield DBConnection_1.DBConnection.getDocumentStore()).collection("queue_jobs"); });
|
|
24
24
|
}
|
|
25
25
|
static enqueue(jobclass, props = {}) {
|
|
26
26
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -50,7 +50,7 @@ class Queue {
|
|
|
50
50
|
yield jobs.updateMany({ status: "running", embedded_queue: true, lease_until: { $lt: now } }, { $set: { status: "pending", worker: null, recovered: true } });
|
|
51
51
|
const token = crypto_1.default.randomUUID();
|
|
52
52
|
const claimed = yield jobs.findOneAndUpdate({ status: "pending", jobclass: { $in: jobclasses }, $or: [{ not_before: null }, { not_before: { $lte: now } }] }, { $set: { status: "running", worker: this.worker, embedded_queue: true, lease_token: token, lease_until: new Date(Date.now() + 60000), started_at: now } }, { sort: { priority: -1, created_at: 1 }, returnDocument: "after" });
|
|
53
|
-
const job =
|
|
53
|
+
const job = claimed;
|
|
54
54
|
if (!job)
|
|
55
55
|
return;
|
|
56
56
|
const filter = { _id: job._id, lease_token: token, status: "running" };
|
package/dist/Queue/QueueJob.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DatabaseId } from "../Database/DatabaseAdapter";
|
|
2
2
|
import { Model } from "../Database/Model";
|
|
3
3
|
import type { Notification } from "../Notifications/Notification";
|
|
4
4
|
export declare class QueueJob extends Model {
|
|
5
5
|
notification_queue_job?: boolean;
|
|
6
|
-
_notification?:
|
|
6
|
+
_notification?: DatabaseId;
|
|
7
7
|
notification?: Notification;
|
|
8
8
|
__table: string;
|
|
9
9
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from "./Router/Router";
|
|
|
19
19
|
export * from "./Router/Request";
|
|
20
20
|
export * from "./Router/Response";
|
|
21
21
|
export * from "./Database/BaseDBDriver";
|
|
22
|
+
export * from "./Database/DatabaseAdapter";
|
|
22
23
|
export * from "./Database/DBDrivers";
|
|
23
24
|
export * from "./Database/QueryBuilder";
|
|
24
25
|
export * from "./Facades/StorageDrivers/BaseStorageDriver";
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ __exportStar(require("./Router/Router"), exports);
|
|
|
35
35
|
__exportStar(require("./Router/Request"), exports);
|
|
36
36
|
__exportStar(require("./Router/Response"), exports);
|
|
37
37
|
__exportStar(require("./Database/BaseDBDriver"), exports);
|
|
38
|
+
__exportStar(require("./Database/DatabaseAdapter"), exports);
|
|
38
39
|
__exportStar(require("./Database/DBDrivers"), exports);
|
|
39
40
|
__exportStar(require("./Database/QueryBuilder"), exports);
|
|
40
41
|
__exportStar(require("./Facades/StorageDrivers/BaseStorageDriver"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webtypen/webframez-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.69",
|
|
4
4
|
"description": "The core package of the typescript based webframez (web-framework) by webtypen.de",
|
|
5
5
|
"homepage": "https://webtypen.de/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,7 +50,6 @@
|
|
|
50
50
|
"lodash": "^4.17.20",
|
|
51
51
|
"mime-types": "^2.1.35",
|
|
52
52
|
"moment-timezone": "^0.6.0",
|
|
53
|
-
"mongodb": "^6.21.0",
|
|
54
53
|
"qs": "^6.11.0",
|
|
55
54
|
"querystring": "^0.2.1"
|
|
56
55
|
}
|