@servicelabsco/nestjs-utility-services 3.0.4 → 3.0.6
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/CHANGELOG.md +50 -6
- package/README.md +164 -60
- package/dist/auth/es6.classes.d.ts +3 -6
- package/dist/auth/es6.classes.js +2 -6
- package/dist/auth/es6.classes.js.map +1 -1
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.js +0 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/common/libraries/common.entity.js +4 -6
- package/dist/common/libraries/common.entity.js.map +1 -1
- package/dist/config/sentry.config.d.ts +1 -1
- package/dist/platformUtility/es6.classes.d.ts +1 -2
- package/dist/platformUtility/es6.classes.js +1 -10
- package/dist/platformUtility/es6.classes.js.map +1 -1
- package/dist/platformUtility/jobs/index.d.ts +0 -1
- package/dist/platformUtility/jobs/index.js +0 -1
- package/dist/platformUtility/jobs/index.js.map +1 -1
- package/dist/platformUtility/services/es6.jobs.service.d.ts +1 -3
- package/dist/platformUtility/services/es6.jobs.service.js +1 -5
- package/dist/platformUtility/services/es6.jobs.service.js.map +1 -1
- package/dist/platformUtility/subscribers/dispatcher.subscriber.d.ts +1 -4
- package/dist/platformUtility/subscribers/dispatcher.subscriber.js +43 -30
- package/dist/platformUtility/subscribers/dispatcher.subscriber.js.map +1 -1
- package/dist/system/es6.classes.d.ts +8 -11
- package/dist/system/es6.classes.js +14 -20
- package/dist/system/es6.classes.js.map +1 -1
- package/dist/system/index.d.ts +1 -0
- package/dist/system/index.js +1 -0
- package/dist/system/index.js.map +1 -1
- package/dist/system/jobs/client.credential.job.d.ts +0 -2
- package/dist/system/jobs/client.credential.job.js +0 -4
- package/dist/system/jobs/client.credential.job.js.map +1 -1
- package/dist/system/jobs/code.fix.script.job.d.ts +0 -4
- package/dist/system/jobs/code.fix.script.job.js +0 -21
- package/dist/system/jobs/code.fix.script.job.js.map +1 -1
- package/dist/system/jobs/index.d.ts +0 -10
- package/dist/system/jobs/index.js +0 -10
- package/dist/system/jobs/index.js.map +1 -1
- package/dist/system/jobs/material.view.job.d.ts +0 -4
- package/dist/system/jobs/material.view.job.js +0 -21
- package/dist/system/jobs/material.view.job.js.map +1 -1
- package/dist/system/jobs/property.job.d.ts +0 -3
- package/dist/system/jobs/property.job.js +0 -9
- package/dist/system/jobs/property.job.js.map +1 -1
- package/dist/system/jobs/recurring.query.job.d.ts +0 -4
- package/dist/system/jobs/recurring.query.job.js +0 -21
- package/dist/system/jobs/recurring.query.job.js.map +1 -1
- package/dist/system/jobs/scheduled.event.job.d.ts +0 -4
- package/dist/system/jobs/scheduled.event.job.js +0 -21
- package/dist/system/jobs/scheduled.event.job.js.map +1 -1
- package/dist/system/services/es6.jobs.service.d.ts +1 -21
- package/dist/system/services/es6.jobs.service.js +1 -41
- package/dist/system/services/es6.jobs.service.js.map +1 -1
- package/dist/system/subscribers/client.credential.subscriber.d.ts +9 -0
- package/dist/system/subscribers/client.credential.subscriber.js +35 -0
- package/dist/system/subscribers/client.credential.subscriber.js.map +1 -0
- package/dist/system/subscribers/code.fix.script.subscriber.d.ts +11 -0
- package/dist/system/subscribers/code.fix.script.subscriber.js +53 -0
- package/dist/system/subscribers/code.fix.script.subscriber.js.map +1 -0
- package/dist/system/subscribers/index.d.ts +6 -0
- package/dist/{auth/jobs → system/subscribers}/index.js +6 -1
- package/dist/system/subscribers/index.js.map +1 -0
- package/dist/system/subscribers/material.view.subscriber.d.ts +11 -0
- package/dist/system/subscribers/material.view.subscriber.js +53 -0
- package/dist/system/subscribers/material.view.subscriber.js.map +1 -0
- package/dist/system/subscribers/property.subscriber.d.ts +10 -0
- package/dist/{auth/subscribers/session.identifier.subscriber.js → system/subscribers/property.subscriber.js} +17 -17
- package/dist/system/subscribers/property.subscriber.js.map +1 -0
- package/dist/system/subscribers/recurring.query.subscriber.d.ts +11 -0
- package/dist/system/subscribers/recurring.query.subscriber.js +53 -0
- package/dist/system/subscribers/recurring.query.subscriber.js.map +1 -0
- package/dist/system/subscribers/scheduled.event.subscriber.d.ts +11 -0
- package/dist/system/subscribers/scheduled.event.subscriber.js +53 -0
- package/dist/system/subscribers/scheduled.event.subscriber.js.map +1 -0
- package/dist/system/system.module.js +1 -1
- package/dist/system/system.module.js.map +1 -1
- package/docs/subscribe-for.md +201 -19
- package/package.json +1 -1
- package/dist/auth/jobs/index.d.ts +0 -1
- package/dist/auth/jobs/index.js.map +0 -1
- package/dist/auth/jobs/session.identifier.job.d.ts +0 -9
- package/dist/auth/jobs/session.identifier.job.js +0 -30
- package/dist/auth/jobs/session.identifier.job.js.map +0 -1
- package/dist/auth/services/es6.jobs.service.d.ts +0 -8
- package/dist/auth/services/es6.jobs.service.js +0 -37
- package/dist/auth/services/es6.jobs.service.js.map +0 -1
- package/dist/auth/subscribers/index.d.ts +0 -1
- package/dist/auth/subscribers/index.js +0 -18
- package/dist/auth/subscribers/index.js.map +0 -1
- package/dist/auth/subscribers/session.identifier.subscriber.d.ts +0 -12
- package/dist/auth/subscribers/session.identifier.subscriber.js.map +0 -1
- package/dist/platformUtility/jobs/remote.request.log.job.d.ts +0 -9
- package/dist/platformUtility/jobs/remote.request.log.job.js +0 -33
- package/dist/platformUtility/jobs/remote.request.log.job.js.map +0 -1
- package/dist/system/jobs/client.job.d.ts +0 -12
- package/dist/system/jobs/client.job.js +0 -46
- package/dist/system/jobs/client.job.js.map +0 -1
- package/dist/system/jobs/code.fix.log.job.d.ts +0 -9
- package/dist/system/jobs/code.fix.log.job.js +0 -33
- package/dist/system/jobs/code.fix.log.job.js.map +0 -1
- package/dist/system/jobs/data.log.job.d.ts +0 -9
- package/dist/system/jobs/data.log.job.js +0 -33
- package/dist/system/jobs/data.log.job.js.map +0 -1
- package/dist/system/jobs/executable.script.job.d.ts +0 -9
- package/dist/system/jobs/executable.script.job.js +0 -33
- package/dist/system/jobs/executable.script.job.js.map +0 -1
- package/dist/system/jobs/mail.event.job.d.ts +0 -9
- package/dist/system/jobs/mail.event.job.js +0 -33
- package/dist/system/jobs/mail.event.job.js.map +0 -1
- package/dist/system/jobs/mail.recipient.job.d.ts +0 -9
- package/dist/system/jobs/mail.recipient.job.js +0 -33
- package/dist/system/jobs/mail.recipient.job.js.map +0 -1
- package/dist/system/jobs/mail.validation.job.d.ts +0 -9
- package/dist/system/jobs/mail.validation.job.js +0 -31
- package/dist/system/jobs/mail.validation.job.js.map +0 -1
- package/dist/system/jobs/mobile.validation.job.d.ts +0 -9
- package/dist/system/jobs/mobile.validation.job.js +0 -31
- package/dist/system/jobs/mobile.validation.job.js.map +0 -1
- package/dist/system/jobs/report.sheet.job.d.ts +0 -9
- package/dist/system/jobs/report.sheet.job.js +0 -33
- package/dist/system/jobs/report.sheet.job.js.map +0 -1
- package/dist/system/jobs/sms.message.job.d.ts +0 -9
- package/dist/system/jobs/sms.message.job.js +0 -31
- package/dist/system/jobs/sms.message.job.js.map +0 -1
|
@@ -14,5 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./client.credential.subscriber"), exports);
|
|
18
|
+
__exportStar(require("./code.fix.script.subscriber"), exports);
|
|
19
|
+
__exportStar(require("./material.view.subscriber"), exports);
|
|
20
|
+
__exportStar(require("./property.subscriber"), exports);
|
|
21
|
+
__exportStar(require("./recurring.query.subscriber"), exports);
|
|
22
|
+
__exportStar(require("./scheduled.event.subscriber"), exports);
|
|
18
23
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/system/subscribers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C;AAAA,+DAA6C;AAAA,6DAA2C;AAAA,wDAAsC;AAAA,+DAA6C;AAAA,+DAA4C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DataSource, InsertEvent, UpdateEvent } from 'typeorm';
|
|
2
|
+
import { CommonSubscriber } from '../../common/libraries/common.subscriber';
|
|
3
|
+
import { MaterialViewEntity } from '../entities/material.view.entity';
|
|
4
|
+
export declare class MaterialViewSubscriber extends CommonSubscriber<MaterialViewEntity> {
|
|
5
|
+
private readonly dataSource;
|
|
6
|
+
constructor(dataSource: DataSource);
|
|
7
|
+
listenTo(): typeof MaterialViewEntity;
|
|
8
|
+
beforeInsert(event: InsertEvent<MaterialViewEntity>): Promise<void>;
|
|
9
|
+
beforeUpdate(event: UpdateEvent<MaterialViewEntity>): Promise<void>;
|
|
10
|
+
private validateTiming;
|
|
11
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MaterialViewSubscriber = void 0;
|
|
13
|
+
const date_fns_1 = require("date-fns");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
const form_exception_1 = require("../../common/exceptions/form.exception");
|
|
16
|
+
const common_subscriber_1 = require("../../common/libraries/common.subscriber");
|
|
17
|
+
const platform_utility_1 = require("../../common/libraries/platform.utility");
|
|
18
|
+
const material_view_entity_1 = require("../entities/material.view.entity");
|
|
19
|
+
let MaterialViewSubscriber = class MaterialViewSubscriber extends common_subscriber_1.CommonSubscriber {
|
|
20
|
+
constructor(dataSource) {
|
|
21
|
+
super();
|
|
22
|
+
this.dataSource = dataSource;
|
|
23
|
+
dataSource.subscribers.push(this);
|
|
24
|
+
}
|
|
25
|
+
listenTo() {
|
|
26
|
+
return material_view_entity_1.MaterialViewEntity;
|
|
27
|
+
}
|
|
28
|
+
async beforeInsert(event) {
|
|
29
|
+
event.entity.attributes = {
|
|
30
|
+
...event.entity.attributes,
|
|
31
|
+
...{},
|
|
32
|
+
};
|
|
33
|
+
this.validateTiming(event.entity?.timing);
|
|
34
|
+
if (!event.entity.last_scheduled_time)
|
|
35
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
36
|
+
}
|
|
37
|
+
async beforeUpdate(event) {
|
|
38
|
+
this.validateTiming(event.entity?.timing);
|
|
39
|
+
if (!event.entity.last_scheduled_time)
|
|
40
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
41
|
+
}
|
|
42
|
+
validateTiming(timing) {
|
|
43
|
+
if (timing && !platform_utility_1.PlatformUtility.isValidCronExpression(timing)) {
|
|
44
|
+
throw new form_exception_1.FormException({ column: 'timing', err: `Invalid cron expression: ${timing}` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.MaterialViewSubscriber = MaterialViewSubscriber;
|
|
49
|
+
exports.MaterialViewSubscriber = MaterialViewSubscriber = __decorate([
|
|
50
|
+
(0, typeorm_1.EventSubscriber)(),
|
|
51
|
+
__metadata("design:paramtypes", [typeorm_1.DataSource])
|
|
52
|
+
], MaterialViewSubscriber);
|
|
53
|
+
//# sourceMappingURL=material.view.subscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material.view.subscriber.js","sourceRoot":"","sources":["../../../src/system/subscribers/material.view.subscriber.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uCAAsC;AACtC,qCAAgF;AAChF,2EAAuE;AACvE,gFAA4E;AAC5E,8EAA0E;AAC1E,2EAAsE;AAO/D,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,oCAAoC;IAC5E,YAA6B,UAAsB;QAC/C,KAAK,EAAE,CAAC;QADiB,eAAU,GAAV,UAAU,CAAY;QAE/C,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACJ,OAAO,yCAAkB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAsC;QACrD,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG;YACtB,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;YAC1B,GAAG,EAAE;SACR,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAsC;QACrD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzG,CAAC;IAEO,cAAc,CAAC,MAAiC;QACpD,IAAI,MAAM,IAAI,CAAC,kCAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,8BAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,4BAA4B,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC;IACL,CAAC;CACJ,CAAA;AAhCY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,yBAAe,GAAE;qCAE2B,oBAAU;GAD1C,sBAAsB,CAgClC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DataSource, InsertEvent, UpdateEvent } from 'typeorm';
|
|
2
|
+
import { CommonSubscriber } from '../../common/libraries/common.subscriber';
|
|
3
|
+
import { PropertyEntity } from '../entities/property.entity';
|
|
4
|
+
export declare class PropertySubscriber extends CommonSubscriber<PropertyEntity> {
|
|
5
|
+
private readonly dataSource;
|
|
6
|
+
constructor(dataSource: DataSource);
|
|
7
|
+
listenTo(): typeof PropertyEntity;
|
|
8
|
+
beforeInsert(event: InsertEvent<PropertyEntity>): Promise<void>;
|
|
9
|
+
beforeUpdate(evt: UpdateEvent<PropertyEntity>): Promise<void>;
|
|
10
|
+
}
|
|
@@ -9,32 +9,32 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.PropertySubscriber = void 0;
|
|
13
13
|
const typeorm_1 = require("typeorm");
|
|
14
14
|
const common_subscriber_1 = require("../../common/libraries/common.subscriber");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
let
|
|
18
|
-
constructor(dataSource
|
|
15
|
+
const custom_crypt_1 = require("../../common/libraries/custom.crypt");
|
|
16
|
+
const property_entity_1 = require("../entities/property.entity");
|
|
17
|
+
let PropertySubscriber = class PropertySubscriber extends common_subscriber_1.CommonSubscriber {
|
|
18
|
+
constructor(dataSource) {
|
|
19
19
|
super();
|
|
20
20
|
this.dataSource = dataSource;
|
|
21
|
-
this.sessionIdentifierJob = sessionIdentifierJob;
|
|
22
21
|
dataSource.subscribers.push(this);
|
|
23
22
|
}
|
|
24
23
|
listenTo() {
|
|
25
|
-
return
|
|
24
|
+
return property_entity_1.PropertyEntity;
|
|
26
25
|
}
|
|
27
|
-
async
|
|
28
|
-
|
|
26
|
+
async beforeInsert(event) {
|
|
27
|
+
if (event.entity.is_encrypted)
|
|
28
|
+
event.entity.value = custom_crypt_1.CustomCrypt.encrypt(event.entity.value);
|
|
29
29
|
}
|
|
30
|
-
async
|
|
31
|
-
|
|
30
|
+
async beforeUpdate(evt) {
|
|
31
|
+
if (evt.entity.is_encrypted && evt.entity.value !== evt.databaseEntity.value)
|
|
32
|
+
evt.entity.value = custom_crypt_1.CustomCrypt.encrypt(evt.entity.value);
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
|
-
exports.
|
|
35
|
-
exports.
|
|
35
|
+
exports.PropertySubscriber = PropertySubscriber;
|
|
36
|
+
exports.PropertySubscriber = PropertySubscriber = __decorate([
|
|
36
37
|
(0, typeorm_1.EventSubscriber)(),
|
|
37
|
-
__metadata("design:paramtypes", [typeorm_1.DataSource
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//# sourceMappingURL=session.identifier.subscriber.js.map
|
|
38
|
+
__metadata("design:paramtypes", [typeorm_1.DataSource])
|
|
39
|
+
], PropertySubscriber);
|
|
40
|
+
//# sourceMappingURL=property.subscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property.subscriber.js","sourceRoot":"","sources":["../../../src/system/subscribers/property.subscriber.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAAgF;AAChF,gFAA4E;AAC5E,sEAAkE;AAClE,iEAA6D;AAQtD,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,oCAAgC;IACpE,YAA6B,UAAsB;QAC/C,KAAK,EAAE,CAAC;QADiB,eAAU,GAAV,UAAU,CAAY;QAE/C,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACJ,OAAO,gCAAc,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAkC;QACjD,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY;YAAE,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,0BAAW,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChG,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAgC;QAC/C,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,GAAG,CAAC,cAAc,CAAC,KAAK;YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,0BAAW,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3I,CAAC;CACJ,CAAA;AAjBY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,yBAAe,GAAE;qCAE2B,oBAAU;GAD1C,kBAAkB,CAiB9B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DataSource, InsertEvent, UpdateEvent } from 'typeorm';
|
|
2
|
+
import { CommonSubscriber } from '../../common/libraries/common.subscriber';
|
|
3
|
+
import { RecurringQueryEntity } from '../entities/recurring.query.entity';
|
|
4
|
+
export declare class RecurringQuerySubscriber extends CommonSubscriber<RecurringQueryEntity> {
|
|
5
|
+
private readonly dataSource;
|
|
6
|
+
constructor(dataSource: DataSource);
|
|
7
|
+
listenTo(): typeof RecurringQueryEntity;
|
|
8
|
+
beforeInsert(event: InsertEvent<RecurringQueryEntity>): Promise<void>;
|
|
9
|
+
beforeUpdate(event: UpdateEvent<RecurringQueryEntity>): Promise<void>;
|
|
10
|
+
private validateTiming;
|
|
11
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RecurringQuerySubscriber = void 0;
|
|
13
|
+
const date_fns_1 = require("date-fns");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
const form_exception_1 = require("../../common/exceptions/form.exception");
|
|
16
|
+
const common_subscriber_1 = require("../../common/libraries/common.subscriber");
|
|
17
|
+
const platform_utility_1 = require("../../common/libraries/platform.utility");
|
|
18
|
+
const recurring_query_entity_1 = require("../entities/recurring.query.entity");
|
|
19
|
+
let RecurringQuerySubscriber = class RecurringQuerySubscriber extends common_subscriber_1.CommonSubscriber {
|
|
20
|
+
constructor(dataSource) {
|
|
21
|
+
super();
|
|
22
|
+
this.dataSource = dataSource;
|
|
23
|
+
dataSource.subscribers.push(this);
|
|
24
|
+
}
|
|
25
|
+
listenTo() {
|
|
26
|
+
return recurring_query_entity_1.RecurringQueryEntity;
|
|
27
|
+
}
|
|
28
|
+
async beforeInsert(event) {
|
|
29
|
+
event.entity.attributes = {
|
|
30
|
+
...event.entity.attributes,
|
|
31
|
+
...{},
|
|
32
|
+
};
|
|
33
|
+
this.validateTiming(event.entity?.timing);
|
|
34
|
+
if (!event.entity.last_scheduled_time)
|
|
35
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
36
|
+
}
|
|
37
|
+
async beforeUpdate(event) {
|
|
38
|
+
this.validateTiming(event.entity?.timing);
|
|
39
|
+
if (!event.entity.last_scheduled_time)
|
|
40
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
41
|
+
}
|
|
42
|
+
validateTiming(timing) {
|
|
43
|
+
if (timing && !platform_utility_1.PlatformUtility.isValidCronExpression(timing)) {
|
|
44
|
+
throw new form_exception_1.FormException({ column: 'timing', err: `Invalid cron expression: ${timing}` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.RecurringQuerySubscriber = RecurringQuerySubscriber;
|
|
49
|
+
exports.RecurringQuerySubscriber = RecurringQuerySubscriber = __decorate([
|
|
50
|
+
(0, typeorm_1.EventSubscriber)(),
|
|
51
|
+
__metadata("design:paramtypes", [typeorm_1.DataSource])
|
|
52
|
+
], RecurringQuerySubscriber);
|
|
53
|
+
//# sourceMappingURL=recurring.query.subscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurring.query.subscriber.js","sourceRoot":"","sources":["../../../src/system/subscribers/recurring.query.subscriber.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uCAAsC;AACtC,qCAAgF;AAChF,2EAAuE;AACvE,gFAA4E;AAC5E,8EAA0E;AAC1E,+EAA0E;AAOnE,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,oCAAsC;IAChF,YAA6B,UAAsB;QAC/C,KAAK,EAAE,CAAC;QADiB,eAAU,GAAV,UAAU,CAAY;QAE/C,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACJ,OAAO,6CAAoB,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAwC;QACvD,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG;YACtB,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;YAC1B,GAAG,EAAE;SACR,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzG,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAwC;QACvD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzG,CAAC;IAEO,cAAc,CAAC,MAAiC;QACpD,IAAI,MAAM,IAAI,CAAC,kCAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,8BAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,4BAA4B,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC;IACL,CAAC;CACJ,CAAA;AAhCY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,yBAAe,GAAE;qCAE2B,oBAAU;GAD1C,wBAAwB,CAgCpC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DataSource, InsertEvent, UpdateEvent } from 'typeorm';
|
|
2
|
+
import { CommonSubscriber } from '../../common/libraries/common.subscriber';
|
|
3
|
+
import { ScheduledEventEntity } from '../entities/scheduled.event.entity';
|
|
4
|
+
export declare class ScheduledEventSubscriber extends CommonSubscriber<ScheduledEventEntity> {
|
|
5
|
+
private readonly dataSource;
|
|
6
|
+
constructor(dataSource: DataSource);
|
|
7
|
+
listenTo(): typeof ScheduledEventEntity;
|
|
8
|
+
beforeInsert(event: InsertEvent<ScheduledEventEntity>): Promise<void>;
|
|
9
|
+
beforeUpdate(event: UpdateEvent<ScheduledEventEntity>): Promise<void>;
|
|
10
|
+
private validateTiming;
|
|
11
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ScheduledEventSubscriber = void 0;
|
|
13
|
+
const date_fns_1 = require("date-fns");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
const form_exception_1 = require("../../common/exceptions/form.exception");
|
|
16
|
+
const common_subscriber_1 = require("../../common/libraries/common.subscriber");
|
|
17
|
+
const platform_utility_1 = require("../../common/libraries/platform.utility");
|
|
18
|
+
const scheduled_event_entity_1 = require("../entities/scheduled.event.entity");
|
|
19
|
+
let ScheduledEventSubscriber = class ScheduledEventSubscriber extends common_subscriber_1.CommonSubscriber {
|
|
20
|
+
constructor(dataSource) {
|
|
21
|
+
super();
|
|
22
|
+
this.dataSource = dataSource;
|
|
23
|
+
dataSource.subscribers.push(this);
|
|
24
|
+
}
|
|
25
|
+
listenTo() {
|
|
26
|
+
return scheduled_event_entity_1.ScheduledEventEntity;
|
|
27
|
+
}
|
|
28
|
+
async beforeInsert(event) {
|
|
29
|
+
event.entity.attributes = {
|
|
30
|
+
...event.entity.attributes,
|
|
31
|
+
...{},
|
|
32
|
+
};
|
|
33
|
+
this.validateTiming(event.entity?.timing);
|
|
34
|
+
if (!event.entity?.last_scheduled_time)
|
|
35
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
36
|
+
}
|
|
37
|
+
async beforeUpdate(event) {
|
|
38
|
+
this.validateTiming(event.entity?.timing);
|
|
39
|
+
if (!event.entity?.last_scheduled_time)
|
|
40
|
+
event.entity.last_scheduled_time = (0, date_fns_1.subMinutes)(new Date(), 15);
|
|
41
|
+
}
|
|
42
|
+
validateTiming(timing) {
|
|
43
|
+
if (timing && !platform_utility_1.PlatformUtility.isValidCronExpression(timing)) {
|
|
44
|
+
throw new form_exception_1.FormException({ column: 'timing', err: `Invalid cron expression: ${timing}` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.ScheduledEventSubscriber = ScheduledEventSubscriber;
|
|
49
|
+
exports.ScheduledEventSubscriber = ScheduledEventSubscriber = __decorate([
|
|
50
|
+
(0, typeorm_1.EventSubscriber)(),
|
|
51
|
+
__metadata("design:paramtypes", [typeorm_1.DataSource])
|
|
52
|
+
], ScheduledEventSubscriber);
|
|
53
|
+
//# sourceMappingURL=scheduled.event.subscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduled.event.subscriber.js","sourceRoot":"","sources":["../../../src/system/subscribers/scheduled.event.subscriber.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uCAAsC;AACtC,qCAAgF;AAChF,2EAAuE;AACvE,gFAA4E;AAC5E,8EAA0E;AAC1E,+EAA0E;AAOnE,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,oCAAsC;IAChF,YAA6B,UAAsB;QAC/C,KAAK,EAAE,CAAC;QADiB,eAAU,GAAV,UAAU,CAAY;QAE/C,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACJ,OAAO,6CAAoB,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAwC;QACvD,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG;YACtB,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;YAC1B,GAAG,EAAE;SACR,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1G,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAwC;QACvD,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE1C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,mBAAmB;YAAE,KAAK,CAAC,MAAM,CAAC,mBAAmB,GAAG,IAAA,qBAAU,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1G,CAAC;IAEO,cAAc,CAAC,MAAiC;QACpD,IAAI,MAAM,IAAI,CAAC,kCAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,8BAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,4BAA4B,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC;IACL,CAAC;CACJ,CAAA;AAhCY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,yBAAe,GAAE;qCAE2B,oBAAU;GAD1C,wBAAwB,CAgCpC"}
|
|
@@ -22,7 +22,7 @@ exports.SystemModule = SystemModule = __decorate([
|
|
|
22
22
|
(0, common_1.Module)({
|
|
23
23
|
imports: [typeorm_1.TypeOrmModule.forFeature(es6_classes_1.default.entities), (0, common_1.forwardRef)(() => auth_module_1.AuthModule), (0, common_1.forwardRef)(() => platform_utility_module_1.PlatformUtilityModule)],
|
|
24
24
|
controllers: es6_classes_1.default.controllers,
|
|
25
|
-
providers: [...es6_classes_1.default.services, ...es6_classes_1.default.jobs],
|
|
25
|
+
providers: [...es6_classes_1.default.services, ...es6_classes_1.default.subscribers, ...es6_classes_1.default.jobs],
|
|
26
26
|
exports: [...es6_classes_1.default.services, ...es6_classes_1.default.jobs],
|
|
27
27
|
})
|
|
28
28
|
], SystemModule);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.module.js","sourceRoot":"","sources":["../../src/system/system.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAoD;AACpD,qDAAiD;AACjD,wFAAmF;AACnF,gEAAuC;AACvC,6CAAgD;AAQzC,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IANxB,IAAA,eAAM,EAAC;QACJ,OAAO,EAAE,CAAC,uBAAa,CAAC,UAAU,CAAC,qBAAU,CAAC,QAAQ,CAAC,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,wBAAU,CAAC,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,+CAAqB,CAAC,CAAC;QAC/H,WAAW,EAAE,qBAAU,CAAC,WAAW;QACnC,SAAS,EAAE,CAAC,GAAG,qBAAU,CAAC,QAAQ,EAAE,GAAG,qBAAU,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"system.module.js","sourceRoot":"","sources":["../../src/system/system.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAoD;AACpD,qDAAiD;AACjD,wFAAmF;AACnF,gEAAuC;AACvC,6CAAgD;AAQzC,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IANxB,IAAA,eAAM,EAAC;QACJ,OAAO,EAAE,CAAC,uBAAa,CAAC,UAAU,CAAC,qBAAU,CAAC,QAAQ,CAAC,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,wBAAU,CAAC,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,+CAAqB,CAAC,CAAC;QAC/H,WAAW,EAAE,qBAAU,CAAC,WAAW;QACnC,SAAS,EAAE,CAAC,GAAG,qBAAU,CAAC,QAAQ,EAAE,GAAG,qBAAU,CAAC,WAAW,EAAE,GAAG,qBAAU,CAAC,IAAI,CAAC;QAClF,OAAO,EAAE,CAAC,GAAG,qBAAU,CAAC,QAAQ,EAAE,GAAG,qBAAU,CAAC,IAAI,CAAC;KACxD,CAAC;GACW,YAAY,CAAG"}
|
package/docs/subscribe-for.md
CHANGED
|
@@ -1,39 +1,221 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Jobs & subscribers — guide for consuming apps
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
This package (`@servicelabsco/nestjs-utility-services`, **NU**) owns many
|
|
4
|
+
TypeORM entities and some platform jobs. Downstream apps (Expense, Access,
|
|
5
|
+
etc.) often need extra side effects or pre-persist mutations on those
|
|
6
|
+
entities — or on their own entities.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This doc is the **contract** for how to do that without fighting NU’s
|
|
9
|
+
dispatcher or double-enqueuing work.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Mental model
|
|
14
|
+
|
|
15
|
+
| When | Where it lives | Mechanism |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Mutate the row **before** it hits the DB (hash secret, encrypt, validate cron, stamp defaults) | Standalone `*.subscriber.ts` extending `CommonSubscriber` | TypeORM `beforeInsert` / `beforeUpdate` |
|
|
18
|
+
| Run **after** the row is saved (cache refresh, schedule event, sync counts, app-local side effects) | `CommonJob` with `@SubscribeFor(Entity)` | `DispatcherSubscriber` → `delayedDispatch` → `handle(DatabaseEventDto)` |
|
|
19
|
+
| Ad-hoc / cron / webhook work **not** tied to an entity save | Plain `CommonJob` (no `@SubscribeFor`) | Call `job.dispatch(...)` / `delayedDispatch(...)` yourself |
|
|
20
|
+
|
|
21
|
+
**Jobs are post-persist queue work. Subscribers own pre-persist mutation.**
|
|
22
|
+
`DispatcherSubscriber` never calls job `beforeInsert` / `beforeUpdate`.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
entity.save()
|
|
26
|
+
│
|
|
27
|
+
├─ beforeInsert / beforeUpdate → your CommonSubscriber (sync, in-transaction)
|
|
28
|
+
├─ SQL INSERT / UPDATE
|
|
29
|
+
└─ afterInsert / afterUpdate → DispatcherSubscriber
|
|
30
|
+
└─ every @SubscribeFor(Entity) job
|
|
31
|
+
delayedDispatch → BullMQ → handle()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## What consuming apps should do
|
|
37
|
+
|
|
38
|
+
### 1. Extra side effects on an NU entity (most common)
|
|
39
|
+
|
|
40
|
+
NU already ships a job for many entities (e.g. `DocumentJob`, `PropertyJob`).
|
|
41
|
+
You usually want **another** job for product-specific work — do **not** fork or
|
|
42
|
+
wrap the platform job.
|
|
13
43
|
|
|
14
44
|
```ts
|
|
15
45
|
import { Injectable } from '@nestjs/common';
|
|
16
|
-
import {
|
|
46
|
+
import {
|
|
47
|
+
CommonJob,
|
|
48
|
+
DatabaseEventDto,
|
|
49
|
+
DocumentEntity,
|
|
50
|
+
SubscribeFor,
|
|
51
|
+
} from '@servicelabsco/nestjs-utility-services';
|
|
17
52
|
|
|
18
53
|
@SubscribeFor(DocumentEntity)
|
|
19
54
|
@Injectable()
|
|
20
55
|
export class LocalDocumentJob extends CommonJob {
|
|
56
|
+
constructor(protected readonly queueService: QueueService /* + your deps */) {
|
|
57
|
+
super('<unique-32-char-md5-hash>'); // must be unique across the whole fleet
|
|
58
|
+
}
|
|
59
|
+
|
|
21
60
|
async handle(evt: DatabaseEventDto<DocumentEntity>) {
|
|
22
|
-
//
|
|
61
|
+
// tenant / product side effects only
|
|
62
|
+
// DocumentJob still runs separately via the same dispatcher fan-out
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Register the job** as a Nest provider in your app module (or your module’s
|
|
68
|
+
`es6.classes.ts` `jobs` array). If it is not in DI, boot fails when
|
|
69
|
+
`DispatcherSubscriber` cannot resolve it.
|
|
70
|
+
|
|
71
|
+
**Worker:** the process with `BULL_QUEUE_WORKER=true` must load the module that
|
|
72
|
+
provides your job, or the queue will not find a handler for that hash.
|
|
73
|
+
|
|
74
|
+
### 2. Pre-persist hooks on an NU (or local) entity
|
|
75
|
+
|
|
76
|
+
Put them on a standalone subscriber. Do **not** put `beforeInsert` /
|
|
77
|
+
`beforeUpdate` on a `@SubscribeFor` job — they will never run via the
|
|
78
|
+
dispatcher.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { DataSource, EventSubscriber, InsertEvent, UpdateEvent } from 'typeorm';
|
|
82
|
+
import { CommonSubscriber } from '@servicelabsco/nestjs-utility-services';
|
|
83
|
+
|
|
84
|
+
@EventSubscriber()
|
|
85
|
+
export class LocalCredentialSubscriber extends CommonSubscriber<YourEntity> {
|
|
86
|
+
constructor(private readonly dataSource: DataSource) {
|
|
87
|
+
super();
|
|
88
|
+
dataSource.subscribers.push(this); // required so TypeORM sees the instance
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
listenTo() {
|
|
92
|
+
return YourEntity;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async beforeInsert(event: InsertEvent<YourEntity>) {
|
|
96
|
+
event.entity.secret = hash(event.entity.secret);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async beforeUpdate(event: UpdateEvent<YourEntity>) {
|
|
100
|
+
// …
|
|
23
101
|
}
|
|
24
102
|
}
|
|
25
103
|
```
|
|
26
104
|
|
|
27
|
-
Register
|
|
28
|
-
|
|
105
|
+
Register the subscriber in your module `providers` (or `es6.classes.subscribers`).
|
|
106
|
+
|
|
107
|
+
Coexistence with NU’s `@SubscribeFor` job on the same entity is **allowed**.
|
|
108
|
+
Boot will not throw.
|
|
109
|
+
|
|
110
|
+
### 3. Both mutation + post-persist for the same entity
|
|
111
|
+
|
|
112
|
+
Use **both** files: subscriber for before*, job with `@SubscribeFor` for after*.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
// ✅ subscriber — mutation only
|
|
116
|
+
async beforeInsert(e) { e.entity.x = normalize(e.entity.x); }
|
|
117
|
+
|
|
118
|
+
// ✅ job — @SubscribeFor(Entity), handle() only
|
|
119
|
+
async handle(evt: DatabaseEventDto<Entity>) { await this.refreshCache(evt.entity); }
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Never** call `this.someSubscribeForJob.delayedDispatch(...)` from the
|
|
123
|
+
standalone subscriber for a job that already has `@SubscribeFor` — that
|
|
124
|
+
enqueues the same work twice.
|
|
125
|
+
|
|
126
|
+
### 4. Your own entity (not from NU)
|
|
127
|
+
|
|
128
|
+
Same rules:
|
|
129
|
+
|
|
130
|
+
- Need queue work on insert/update → `@SubscribeFor(YourEntity)` on a `CommonJob`.
|
|
131
|
+
- Need before* → standalone `CommonSubscriber`.
|
|
132
|
+
- Need neither → no subscriber and no `@SubscribeFor` (plain services are enough).
|
|
133
|
+
|
|
134
|
+
Do **not** create empty jobs that only `return evt.entity` — they still enqueue
|
|
135
|
+
Bull work on every save.
|
|
136
|
+
|
|
137
|
+
### 5. Manual / scheduled jobs (no entity binding)
|
|
138
|
+
|
|
139
|
+
Omit `@SubscribeFor`. Dispatch explicitly:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
await this.myJob.dispatch(payload);
|
|
143
|
+
await this.myJob.delayedDispatch(payload, 5_000);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Keep a stable hash in `super('…')` and register the job in DI + worker like any
|
|
147
|
+
other job.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Wiring checklist (consuming app)
|
|
29
152
|
|
|
30
|
-
|
|
153
|
+
1. **Import NU modules** your app needs (`AuthModule`, `SystemModule`,
|
|
154
|
+
`PlatformUtilityModule`, …) so `DispatcherSubscriber` and platform jobs load.
|
|
155
|
+
2. **Provide** every `@SubscribeFor` job and every standalone subscriber in a
|
|
156
|
+
Nest module that the API **and** worker import.
|
|
157
|
+
3. **Worker** (`BULL_QUEUE_WORKER=true`) must resolve the same job providers;
|
|
158
|
+
otherwise jobs enqueue but never run.
|
|
159
|
+
4. **Hash** (`super('…')`) must be unique — collisions break `PlatformUtility.getJob`
|
|
160
|
+
/ Bull routing.
|
|
161
|
+
5. Prefer your app’s `es6.classes.ts` pattern if you use `slnu syncClassess`;
|
|
162
|
+
otherwise list classes in `@Module({ providers, exports })`.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Behaviour reference
|
|
31
167
|
|
|
32
168
|
| Hook | Behaviour |
|
|
33
169
|
| --- | --- |
|
|
34
|
-
| `afterInsert` / `afterUpdate` | Fan-out to **all**
|
|
35
|
-
| `beforeInsert` / `beforeUpdate` | **
|
|
36
|
-
| Standalone
|
|
170
|
+
| `afterInsert` / `afterUpdate` | Fan-out to **all** `@SubscribeFor` jobs for that entity (registration order, sequential enqueue). |
|
|
171
|
+
| `beforeInsert` / `beforeUpdate` | **Only** on standalone `CommonSubscriber`s. Never routed to jobs. |
|
|
172
|
+
| Standalone subscriber + `@SubscribeFor` | Allowed. Mutation on subscriber; post-persist via dispatcher. |
|
|
173
|
+
| Transactional saves | Dispatch is buffered until commit (see `CommonSubscriber` / dispatcher); rolled back on rollback. |
|
|
174
|
+
|
|
175
|
+
Platform modules usually register before the app, so NU’s job is typically
|
|
176
|
+
**first** when multiple jobs bind the same entity.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Anti-patterns
|
|
181
|
+
|
|
182
|
+
| Don’t | Do instead |
|
|
183
|
+
| --- | --- |
|
|
184
|
+
| Put `beforeInsert` on a `@SubscribeFor` job | Standalone `CommonSubscriber` |
|
|
185
|
+
| `delayedDispatch` the same `@SubscribeFor` job from a subscriber | Let `DispatcherSubscriber` enqueue once |
|
|
186
|
+
| Empty job (`handle` no-op / `return evt.entity`) “for later” | Omit the job until you have real work |
|
|
187
|
+
| Subclass / re-export NU’s job just to add a line of logic | Second `@SubscribeFor` job in your app |
|
|
188
|
+
| Forget to register the job on the worker | Import the same module in `worker` bootstrap |
|
|
189
|
+
| Hand-roll a pass-through subscriber that only calls `entityJob.delayedDispatch` | `@SubscribeFor` on the job |
|
|
190
|
+
|
|
191
|
+
---
|
|
37
192
|
|
|
38
|
-
|
|
39
|
-
|
|
193
|
+
## What NU already owns (do not reimplement)
|
|
194
|
+
|
|
195
|
+
Examples of platform post-persist jobs (non-exhaustive): document/comment count
|
|
196
|
+
sync, property cache refresh, client-credential cache, credential IP cache,
|
|
197
|
+
column/relationship mappers, user-group ACL sync, scheduled / recurring /
|
|
198
|
+
material-view / code-fix scheduling.
|
|
199
|
+
|
|
200
|
+
Examples of platform **pre-persist** subscribers: property encryption, client
|
|
201
|
+
credential hashing, cron validation + defaults for scheduled events, recurring
|
|
202
|
+
queries, material views, code-fix scripts.
|
|
203
|
+
|
|
204
|
+
If NU already does the work you need, call its services or rely on its job —
|
|
205
|
+
don’t duplicate with another empty or overlapping job.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Quick decision tree
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
Need something on entity save?
|
|
213
|
+
├─ Change fields before SQL?
|
|
214
|
+
│ └─ CommonSubscriber + beforeInsert/beforeUpdate
|
|
215
|
+
├─ Side effects after SQL?
|
|
216
|
+
│ ├─ Already covered by an NU @SubscribeFor job?
|
|
217
|
+
│ │ └─ Add your own @SubscribeFor job (fan-out) if product-specific
|
|
218
|
+
│ └─ Else @SubscribeFor on a new CommonJob
|
|
219
|
+
└─ Not tied to a save?
|
|
220
|
+
└─ CommonJob without @SubscribeFor; dispatch manually
|
|
221
|
+
```
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './session.identifier.job';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/jobs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAwC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { DatabaseEventDto } from '../../common/dtos/database.event.dto';
|
|
2
|
-
import { CommonJob } from '../../common/libraries/common.job';
|
|
3
|
-
import { QueueService } from '../../platformUtility/services/queue.service';
|
|
4
|
-
import { SessionIdentifierEntity } from '../entities/session.identifier.entity';
|
|
5
|
-
export declare class SessionIdentifierJob extends CommonJob {
|
|
6
|
-
protected readonly queueService: QueueService;
|
|
7
|
-
constructor(queueService: QueueService);
|
|
8
|
-
handle(evt: DatabaseEventDto<SessionIdentifierEntity>): Promise<SessionIdentifierEntity>;
|
|
9
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.SessionIdentifierJob = void 0;
|
|
13
|
-
const common_1 = require("@nestjs/common");
|
|
14
|
-
const common_job_1 = require("../../common/libraries/common.job");
|
|
15
|
-
const queue_service_1 = require("../../platformUtility/services/queue.service");
|
|
16
|
-
let SessionIdentifierJob = class SessionIdentifierJob extends common_job_1.CommonJob {
|
|
17
|
-
constructor(queueService) {
|
|
18
|
-
super('29692aaae7ba9e4217568e6c4ba3b36c');
|
|
19
|
-
this.queueService = queueService;
|
|
20
|
-
}
|
|
21
|
-
async handle(evt) {
|
|
22
|
-
return evt.entity;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
exports.SessionIdentifierJob = SessionIdentifierJob;
|
|
26
|
-
exports.SessionIdentifierJob = SessionIdentifierJob = __decorate([
|
|
27
|
-
(0, common_1.Injectable)(),
|
|
28
|
-
__metadata("design:paramtypes", [queue_service_1.QueueService])
|
|
29
|
-
], SessionIdentifierJob);
|
|
30
|
-
//# sourceMappingURL=session.identifier.job.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.identifier.job.js","sourceRoot":"","sources":["../../../src/auth/jobs/session.identifier.job.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAE5C,kEAA8D;AAC9D,gFAA4E;AAGrE,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sBAAS;IAC/C,YAA+B,YAA0B;QACrD,KAAK,CAAC,kCAAkC,CAAC,CAAC;QADf,iBAAY,GAAZ,YAAY,CAAc;IAEzD,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAA8C;QACvD,OAAO,GAAG,CAAC,MAAM,CAAC;IACtB,CAAC;CACJ,CAAA;AAPY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAEoC,4BAAY;GADhD,oBAAoB,CAOhC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { SessionIdentifierJob } from '../jobs/session.identifier.job';
|
|
2
|
-
export declare class Es6JobsService {
|
|
3
|
-
private readonly sessionIdentifierJob;
|
|
4
|
-
private jobs;
|
|
5
|
-
constructor(sessionIdentifierJob: SessionIdentifierJob);
|
|
6
|
-
alignJobs(): void;
|
|
7
|
-
setJobs(): void;
|
|
8
|
-
}
|