@modern-admin/queue 0.6.0 → 0.9.0
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 +33 -0
- package/dist/cron/cron.constants.d.ts +1 -1
- package/dist/cron/cron.constants.js +1 -1
- package/dist/cron/cron.processor.d.ts +1 -1
- package/dist/cron/cron.processor.d.ts.map +1 -1
- package/dist/cron/cron.processor.js +2 -1
- package/dist/cron/cron.processor.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/queue.module.d.ts +1 -0
- package/dist/queue.module.d.ts.map +1 -1
- package/dist/queue.module.js +3 -2
- package/dist/queue.module.js.map +1 -1
- package/dist/retention/index.d.ts +6 -0
- package/dist/retention/index.d.ts.map +1 -0
- package/dist/retention/index.js +5 -0
- package/dist/retention/index.js.map +1 -0
- package/dist/retention/retention.constants.d.ts +3 -0
- package/dist/retention/retention.constants.d.ts.map +1 -0
- package/dist/retention/retention.constants.js +3 -0
- package/dist/retention/retention.constants.js.map +1 -0
- package/dist/retention/retention.module.d.ts +10 -0
- package/dist/retention/retention.module.d.ts.map +1 -0
- package/dist/retention/retention.module.js +50 -0
- package/dist/retention/retention.module.js.map +1 -0
- package/dist/retention/retention.service.d.ts +15 -0
- package/dist/retention/retention.service.d.ts.map +1 -0
- package/dist/retention/retention.service.js +91 -0
- package/dist/retention/retention.service.js.map +1 -0
- package/dist/retention/retention.tokens.d.ts +2 -0
- package/dist/retention/retention.tokens.d.ts.map +1 -0
- package/dist/retention/retention.tokens.js +2 -0
- package/dist/retention/retention.tokens.js.map +1 -0
- package/dist/retention/retention.types.d.ts +26 -0
- package/dist/retention/retention.types.d.ts.map +1 -0
- package/dist/retention/retention.types.js +2 -0
- package/dist/retention/retention.types.js.map +1 -0
- package/package.json +4 -1
- package/src/cron/cron.constants.ts +1 -1
- package/src/cron/cron.processor.ts +1 -1
- package/src/index.ts +13 -0
- package/src/queue.module.ts +6 -2
- package/src/retention/index.ts +11 -0
- package/src/retention/retention.constants.ts +2 -0
- package/src/retention/retention.module.ts +42 -0
- package/src/retention/retention.service.ts +91 -0
- package/src/retention/retention.tokens.ts +1 -0
- package/src/retention/retention.types.ts +30 -0
package/README.md
CHANGED
|
@@ -20,6 +20,39 @@ bun add @modern-admin/queue
|
|
|
20
20
|
Setup guides, architecture, and usage examples live in the
|
|
21
21
|
[Modern Admin README](https://github.com/modern-admin/modern-admin#readme).
|
|
22
22
|
|
|
23
|
+
## System retention
|
|
24
|
+
|
|
25
|
+
`RetentionModule` runs history and audit-log pruning in the existing BullMQ
|
|
26
|
+
cron queue. Import `QueueModule.forRoot()` once, then configure whichever
|
|
27
|
+
stores need retention:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { QueueModule, RetentionModule } from '@modern-admin/queue'
|
|
31
|
+
|
|
32
|
+
@Module({
|
|
33
|
+
imports: [
|
|
34
|
+
QueueModule.forRoot({ connection: process.env.REDIS_URL! }),
|
|
35
|
+
RetentionModule.forRoot({
|
|
36
|
+
cron: '0 3 * * *',
|
|
37
|
+
history: {
|
|
38
|
+
store: system.historyStore,
|
|
39
|
+
keepDays: 90,
|
|
40
|
+
keepLast: 100,
|
|
41
|
+
},
|
|
42
|
+
auditLog: {
|
|
43
|
+
store: system.logStore,
|
|
44
|
+
keepDays: 365,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
export class AppModule {}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The task uses the cron worker's distributed lock, retries failures three
|
|
53
|
+
times, and does not run when no `keepDays`/`keepLast` bound is configured.
|
|
54
|
+
History `keepLast` is per record; audit-log `keepLast` is global.
|
|
55
|
+
|
|
23
56
|
## License
|
|
24
57
|
|
|
25
58
|
[MIT](https://github.com/modern-admin/modern-admin/blob/main/LICENSE) © Modern Admin
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WorkerHost } from '@nestjs/bullmq';
|
|
2
2
|
import type { Job, Queue } from 'bullmq';
|
|
3
|
-
import
|
|
3
|
+
import { CronService } from './cron.service.js';
|
|
4
4
|
export declare class CronProcessor extends WorkerHost {
|
|
5
5
|
private readonly cronService;
|
|
6
6
|
private readonly cronQueue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron.processor.d.ts","sourceRoot":"","sources":["../../src/cron/cron.processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAOxC,OAAO,
|
|
1
|
+
{"version":3,"file":"cron.processor.d.ts","sourceRoot":"","sources":["../../src/cron/cron.processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAOxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,qBACa,aAAc,SAAQ,UAAU;IAIzC,OAAO,CAAC,QAAQ,CAAC,WAAW;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IAExD,YACmB,WAAW,EAAE,WAAW,EACC,SAAS,EAAE,KAAK,EAG3D;IAEK,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlE;YAEa,eAAe;YAmCf,cAAc;CAe7B"}
|
|
@@ -14,6 +14,7 @@ var CronProcessor_1;
|
|
|
14
14
|
import { InjectQueue, Processor, WorkerHost } from '@nestjs/bullmq';
|
|
15
15
|
import { Logger } from '@nestjs/common';
|
|
16
16
|
import { CRON_LOCK_PREFIX, CRON_QUEUE, DEFAULT_CRON_LOCK_TTL, DEFAULT_CRON_WORKER_CONCURRENCY, } from './cron.constants.js';
|
|
17
|
+
import { CronService } from './cron.service.js';
|
|
17
18
|
let CronProcessor = CronProcessor_1 = class CronProcessor extends WorkerHost {
|
|
18
19
|
constructor(cronService, cronQueue) {
|
|
19
20
|
super();
|
|
@@ -77,7 +78,7 @@ let CronProcessor = CronProcessor_1 = class CronProcessor extends WorkerHost {
|
|
|
77
78
|
CronProcessor = CronProcessor_1 = __decorate([
|
|
78
79
|
Processor(CRON_QUEUE, { concurrency: DEFAULT_CRON_WORKER_CONCURRENCY }),
|
|
79
80
|
__param(1, InjectQueue(CRON_QUEUE)),
|
|
80
|
-
__metadata("design:paramtypes", [
|
|
81
|
+
__metadata("design:paramtypes", [CronService, Function])
|
|
81
82
|
], CronProcessor);
|
|
82
83
|
export { CronProcessor };
|
|
83
84
|
//# sourceMappingURL=cron.processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron.processor.js","sourceRoot":"","sources":["../../src/cron/cron.processor.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEvC,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"cron.processor.js","sourceRoot":"","sources":["../../src/cron/cron.processor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { QueueModule } from './queue.module.js';
|
|
2
2
|
export type { QueueModuleOptions, QueueRootOptions } from './queue.types.js';
|
|
3
3
|
export { CronModule, CronService, CronProcessor, CronTask, CRON_TASK_META, CRON_QUEUE, CRON_LOCK_PREFIX, DEFAULT_CRON_WORKER_CONCURRENCY, DEFAULT_CRON_LOCK_TTL, type CronTaskOptions, type CronHandler, type CronTaskDefinition, } from './cron';
|
|
4
|
+
export { RetentionModule, RetentionService, RETENTION_OPTIONS, DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK, type AuditLogRetentionTarget, type HistoryRetentionTarget, type PrunableStore, type RetentionModuleOptions, type RetentionRunResult, } from './retention';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,QAAQ,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,QAAQ,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,QAAQ,CAAA;AAEf,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// @modern-admin/queue — BullMQ queue + cron scheduling for NestJS.
|
|
2
2
|
export { QueueModule } from './queue.module.js';
|
|
3
3
|
export { CronModule, CronService, CronProcessor, CronTask, CRON_TASK_META, CRON_QUEUE, CRON_LOCK_PREFIX, DEFAULT_CRON_WORKER_CONCURRENCY, DEFAULT_CRON_LOCK_TTL, } from './cron';
|
|
4
|
+
export { RetentionModule, RetentionService, RETENTION_OPTIONS, DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK, } from './retention';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAG/C,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,QAAQ,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,qBAAqB,GAItB,MAAM,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAG/C,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,QAAQ,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,qBAAqB,GAItB,MAAM,QAAQ,CAAA;AAEf,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,GAMtB,MAAM,aAAa,CAAA"}
|
package/dist/queue.module.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type DynamicModule } from '@nestjs/common';
|
|
2
2
|
import type { QueueModuleOptions, QueueRootOptions } from './queue.types.js';
|
|
3
|
+
export declare const normalizeQueueConnection: (connection: QueueRootOptions['connection']) => object;
|
|
3
4
|
/**
|
|
4
5
|
* BullMQ integration module for modern-admin NestJS applications.
|
|
5
6
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.module.d.ts","sourceRoot":"","sources":["../src/queue.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,qBACa,WAAW;IACtB;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAWvD;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;QACxB,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;QAClC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;QAClB,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;KACjF,GAAG,aAAa,CAkBhB;IAED;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAY1D;CACF"}
|
|
1
|
+
{"version":3,"file":"queue.module.d.ts","sourceRoot":"","sources":["../src/queue.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,gBAAgB,CAAA;AAE3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE5E,eAAO,MAAM,wBAAwB,eACvB,gBAAgB,CAAC,YAAY,CAAC,KACzC,MAA2E,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,qBACa,WAAW;IACtB;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAWvD;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;QACxB,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;QAClC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;QAClB,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;KACjF,GAAG,aAAa,CAkBhB;IAED;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAY1D;CACF"}
|
package/dist/queue.module.js
CHANGED
|
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var QueueModule_1;
|
|
8
8
|
import { Module } from '@nestjs/common';
|
|
9
9
|
import { BullModule } from '@nestjs/bullmq';
|
|
10
|
+
export const normalizeQueueConnection = (connection) => typeof connection === 'string' ? { url: connection } : connection;
|
|
10
11
|
/**
|
|
11
12
|
* BullMQ integration module for modern-admin NestJS applications.
|
|
12
13
|
*
|
|
@@ -34,7 +35,7 @@ let QueueModule = QueueModule_1 = class QueueModule {
|
|
|
34
35
|
global: true,
|
|
35
36
|
imports: [
|
|
36
37
|
BullModule.forRoot({
|
|
37
|
-
connection: options.connection,
|
|
38
|
+
connection: normalizeQueueConnection(options.connection),
|
|
38
39
|
defaultJobOptions: options.defaultJobOptions,
|
|
39
40
|
}),
|
|
40
41
|
],
|
|
@@ -64,7 +65,7 @@ let QueueModule = QueueModule_1 = class QueueModule {
|
|
|
64
65
|
useFactory: async (...args) => {
|
|
65
66
|
const resolved = await opts.useFactory(...args);
|
|
66
67
|
return {
|
|
67
|
-
connection: resolved.connection,
|
|
68
|
+
connection: normalizeQueueConnection(resolved.connection),
|
|
68
69
|
defaultJobOptions: resolved.defaultJobOptions,
|
|
69
70
|
};
|
|
70
71
|
},
|
package/dist/queue.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.module.js","sourceRoot":"","sources":["../src/queue.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAsB,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB;;;OAGG;IACI,AAAP,MAAM,CAAC,OAAO,CAAC,OAAyB;QACtC,OAAO;YACL,MAAM,eAAa;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,UAAU,CAAC,OAAO,CAAC;oBACjB,UAAU,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"queue.module.js","sourceRoot":"","sources":["../src/queue.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAsB,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,UAA0C,EAClC,EAAE,CAAC,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;AAE9E;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB;;;OAGG;IACI,AAAP,MAAM,CAAC,OAAO,CAAC,OAAyB;QACtC,OAAO;YACL,MAAM,eAAa;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,UAAU,CAAC,OAAO,CAAC;oBACjB,UAAU,EAAE,wBAAwB,CAAC,OAAO,CAAC,UAAU,CAAC;oBACxD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;iBAC7C,CAAC;aACH;SACF,CAAA;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,AAAP,MAAM,CAAC,YAAY,CAAC,IAInB;QACC,OAAO;YACL,MAAM,eAAa;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,UAAU,CAAC,YAAY,CAAC;oBACtB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,MAAM,EAAE,IAAI,CAAC,MAAiB;oBAC9B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;wBACvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAA;wBAC/C,OAAO;4BACL,UAAU,EAAE,wBAAwB,CAAC,QAAQ,CAAC,UAAU,CAAC;4BACzD,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;yBAC9C,CAAA;oBACH,CAAC;iBACF,CAAC;aACH;SACF,CAAA;IACH,CAAC;IAED;;;OAGG;IACI,AAAP,MAAM,CAAC,QAAQ,CAAC,OAA2B;QACzC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/C,UAAU,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,CACnC,CAAA;QACD,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACrD,UAAU,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAC1C,CAAA;QACD,OAAO;YACL,MAAM,eAAa;YACnB,OAAO,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,WAAW,CAAC;YAC1C,OAAO,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,WAAW,CAAC;SAC3C,CAAA;IACH,CAAC;CACF,CAAA;AAxEY,WAAW;IADvB,MAAM,CAAC,EAAE,CAAC;GACE,WAAW,CAwEvB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { RetentionModule } from './retention.module.js';
|
|
2
|
+
export { RetentionService } from './retention.service.js';
|
|
3
|
+
export { RETENTION_OPTIONS } from './retention.tokens.js';
|
|
4
|
+
export { DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK } from './retention.constants.js';
|
|
5
|
+
export type { AuditLogRetentionTarget, HistoryRetentionTarget, PrunableStore, RetentionModuleOptions, RetentionRunResult, } from './retention.types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/retention/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACxF,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { RetentionModule } from './retention.module.js';
|
|
2
|
+
export { RetentionService } from './retention.service.js';
|
|
3
|
+
export { RETENTION_OPTIONS } from './retention.tokens.js';
|
|
4
|
+
export { DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK } from './retention.constants.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/retention/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.constants.d.ts","sourceRoot":"","sources":["../../src/retention/retention.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAC1D,eAAO,MAAM,sBAAsB,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.constants.js","sourceRoot":"","sources":["../../src/retention/retention.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAAqB,CAAA;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { RetentionModuleOptions } from './retention.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Schedules history and action-log pruning as a durable BullMQ cron task.
|
|
5
|
+
* Requires `QueueModule.forRoot()` in the host application's root module.
|
|
6
|
+
*/
|
|
7
|
+
export declare class RetentionModule {
|
|
8
|
+
static forRoot(options: RetentionModuleOptions): DynamicModule;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=retention.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.module.d.ts","sourceRoot":"","sources":["../../src/retention/retention.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,gBAAgB,CAAA;AAI3D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAmBlE;;;GAGG;AACH,qBACa,eAAe;IAC1B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,aAAa,CAW7D;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var RetentionModule_1;
|
|
8
|
+
import { Module } from '@nestjs/common';
|
|
9
|
+
import { CronModule } from '../cron/cron.module.js';
|
|
10
|
+
import { RetentionService } from './retention.service.js';
|
|
11
|
+
import { RETENTION_OPTIONS } from './retention.tokens.js';
|
|
12
|
+
const assertBound = (name, value) => {
|
|
13
|
+
if (value === undefined)
|
|
14
|
+
return;
|
|
15
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
|
|
16
|
+
throw new Error(`${name} must be a non-negative integer`);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const validateOptions = (options) => {
|
|
20
|
+
if (options.cron !== undefined && options.cron.trim().length === 0) {
|
|
21
|
+
throw new Error('retention cron must not be empty');
|
|
22
|
+
}
|
|
23
|
+
assertBound('history.keepLast', options.history?.keepLast);
|
|
24
|
+
assertBound('history.keepDays', options.history?.keepDays);
|
|
25
|
+
assertBound('auditLog.keepLast', options.auditLog?.keepLast);
|
|
26
|
+
assertBound('auditLog.keepDays', options.auditLog?.keepDays);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Schedules history and action-log pruning as a durable BullMQ cron task.
|
|
30
|
+
* Requires `QueueModule.forRoot()` in the host application's root module.
|
|
31
|
+
*/
|
|
32
|
+
let RetentionModule = RetentionModule_1 = class RetentionModule {
|
|
33
|
+
static forRoot(options) {
|
|
34
|
+
validateOptions(options);
|
|
35
|
+
return {
|
|
36
|
+
module: RetentionModule_1,
|
|
37
|
+
imports: [CronModule],
|
|
38
|
+
providers: [
|
|
39
|
+
{ provide: RETENTION_OPTIONS, useValue: options },
|
|
40
|
+
RetentionService,
|
|
41
|
+
],
|
|
42
|
+
exports: [RetentionService],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
RetentionModule = RetentionModule_1 = __decorate([
|
|
47
|
+
Module({})
|
|
48
|
+
], RetentionModule);
|
|
49
|
+
export { RetentionModule };
|
|
50
|
+
//# sourceMappingURL=retention.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.module.js","sourceRoot":"","sources":["../../src/retention/retention.module.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAsB,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAGzD,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,KAAyB,EAAQ,EAAE;IACpE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAM;IAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iCAAiC,CAAC,CAAA;IAC3D,CAAC;AACH,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,OAA+B,EAAQ,EAAE;IAChE,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACrD,CAAC;IACD,WAAW,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC1D,WAAW,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC1D,WAAW,CAAC,mBAAmB,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC5D,WAAW,CAAC,mBAAmB,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAC9D,CAAC,CAAA;AAED;;;GAGG;AAEI,IAAM,eAAe,uBAArB,MAAM,eAAe;IACnB,AAAP,MAAM,CAAC,OAAO,CAAC,OAA+B;QAC5C,eAAe,CAAC,OAAO,CAAC,CAAA;QACxB,OAAO;YACL,MAAM,mBAAiB;YACvB,OAAO,EAAE,CAAC,UAAU,CAAC;YACrB,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE;gBACjD,gBAAgB;aACjB;YACD,OAAO,EAAE,CAAC,gBAAgB,CAAC;SAC5B,CAAA;IACH,CAAC;CACF,CAAA;AAbY,eAAe;IAD3B,MAAM,CAAC,EAAE,CAAC;GACE,eAAe,CAa3B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { CronService } from '../cron/cron.service.js';
|
|
3
|
+
import type { RetentionModuleOptions, RetentionRunResult } from './retention.types.js';
|
|
4
|
+
export declare class RetentionService implements OnModuleInit {
|
|
5
|
+
private readonly options;
|
|
6
|
+
private readonly cron;
|
|
7
|
+
constructor(options: RetentionModuleOptions, cron: CronService);
|
|
8
|
+
onModuleInit(): void;
|
|
9
|
+
/** Execute every configured retention target. Called by the BullMQ worker. */
|
|
10
|
+
run(): Promise<RetentionRunResult>;
|
|
11
|
+
private hasWork;
|
|
12
|
+
private pruneHistory;
|
|
13
|
+
private pruneAuditLog;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=retention.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.service.d.ts","sourceRoot":"","sources":["../../src/retention/retention.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAGrD,OAAO,KAAK,EAGV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,sBAAsB,CAAA;AAK7B,qBACa,gBAAiB,YAAW,YAAY;IAEtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YAC8C,OAAO,EAAE,sBAAsB,EAC1D,IAAI,EAAE,WAAW,EAChC;IAEJ,YAAY,IAAI,IAAI,CAcnB;IAED,8EAA8E;IACxE,GAAG,IAAI,OAAO,CAAC,kBAAkB,CAAC,CA2BvC;IAED,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,aAAa;CAOtB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
14
|
+
import { CronService } from '../cron/cron.service.js';
|
|
15
|
+
import { DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK } from './retention.constants.js';
|
|
16
|
+
import { RETENTION_OPTIONS } from './retention.tokens.js';
|
|
17
|
+
const hasBounds = (retention) => retention.keepLast !== undefined || retention.keepDays !== undefined;
|
|
18
|
+
let RetentionService = class RetentionService {
|
|
19
|
+
constructor(options, cron) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.cron = cron;
|
|
22
|
+
}
|
|
23
|
+
onModuleInit() {
|
|
24
|
+
if (!this.hasWork())
|
|
25
|
+
return;
|
|
26
|
+
this.cron.register({
|
|
27
|
+
name: SYSTEM_RETENTION_TASK,
|
|
28
|
+
cron: this.options.cron ?? DEFAULT_RETENTION_CRON,
|
|
29
|
+
skipIfRunning: true,
|
|
30
|
+
opts: {
|
|
31
|
+
attempts: 3,
|
|
32
|
+
backoff: { type: 'exponential', delay: 1_000 },
|
|
33
|
+
...this.options.jobOptions,
|
|
34
|
+
},
|
|
35
|
+
handler: () => this.run(),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** Execute every configured retention target. Called by the BullMQ worker. */
|
|
39
|
+
async run() {
|
|
40
|
+
const result = {};
|
|
41
|
+
const failures = [];
|
|
42
|
+
if (this.options.history && hasBounds(this.options.history)) {
|
|
43
|
+
try {
|
|
44
|
+
result.history = await this.pruneHistory(this.options.history);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
failures.push(err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (this.options.auditLog && hasBounds(this.options.auditLog)) {
|
|
51
|
+
try {
|
|
52
|
+
result.auditLog = await this.pruneAuditLog(this.options.auditLog);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
failures.push(err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (failures.length === 1) {
|
|
59
|
+
throw failures[0];
|
|
60
|
+
}
|
|
61
|
+
if (failures.length > 1) {
|
|
62
|
+
throw new AggregateError(failures, 'Multiple retention targets failed');
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
hasWork() {
|
|
67
|
+
return Boolean((this.options.history && hasBounds(this.options.history))
|
|
68
|
+
|| (this.options.auditLog && hasBounds(this.options.auditLog)));
|
|
69
|
+
}
|
|
70
|
+
pruneHistory(target) {
|
|
71
|
+
const retention = {
|
|
72
|
+
...(target.keepLast !== undefined ? { keepLast: target.keepLast } : {}),
|
|
73
|
+
...(target.keepDays !== undefined ? { keepDays: target.keepDays } : {}),
|
|
74
|
+
};
|
|
75
|
+
return target.store.prune(retention);
|
|
76
|
+
}
|
|
77
|
+
pruneAuditLog(target) {
|
|
78
|
+
const retention = {
|
|
79
|
+
...(target.keepLast !== undefined ? { keepLast: target.keepLast } : {}),
|
|
80
|
+
...(target.keepDays !== undefined ? { keepDays: target.keepDays } : {}),
|
|
81
|
+
};
|
|
82
|
+
return target.store.prune(retention);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
RetentionService = __decorate([
|
|
86
|
+
Injectable(),
|
|
87
|
+
__param(0, Inject(RETENTION_OPTIONS)),
|
|
88
|
+
__metadata("design:paramtypes", [Object, CronService])
|
|
89
|
+
], RetentionService);
|
|
90
|
+
export { RetentionService };
|
|
91
|
+
//# sourceMappingURL=retention.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.service.js","sourceRoot":"","sources":["../../src/retention/retention.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.tokens.d.ts","sourceRoot":"","sources":["../../src/retention/retention.tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,eAAqD,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.tokens.js","sourceRoot":"","sources":["../../src/retention/retention.tokens.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ActionLogRetention, HistoryRetention } from '@modern-admin/core';
|
|
2
|
+
import type { JobsOptions } from 'bullmq';
|
|
3
|
+
export interface PrunableStore<TRetention> {
|
|
4
|
+
prune(retention: TRetention): Promise<number>;
|
|
5
|
+
}
|
|
6
|
+
export interface HistoryRetentionTarget extends HistoryRetention {
|
|
7
|
+
store: PrunableStore<HistoryRetention>;
|
|
8
|
+
}
|
|
9
|
+
export interface AuditLogRetentionTarget extends ActionLogRetention {
|
|
10
|
+
store: PrunableStore<ActionLogRetention>;
|
|
11
|
+
}
|
|
12
|
+
export interface RetentionModuleOptions {
|
|
13
|
+
/** BullMQ cron expression. Defaults to every day at 03:00 UTC. */
|
|
14
|
+
cron?: string;
|
|
15
|
+
/** Revision-history retention. `keepLast` is evaluated per record. */
|
|
16
|
+
history?: HistoryRetentionTarget;
|
|
17
|
+
/** Action-log retention. `keepLast` is evaluated globally. */
|
|
18
|
+
auditLog?: AuditLogRetentionTarget;
|
|
19
|
+
/** BullMQ options for each scheduled maintenance job. */
|
|
20
|
+
jobOptions?: Omit<JobsOptions, 'repeat'>;
|
|
21
|
+
}
|
|
22
|
+
export interface RetentionRunResult {
|
|
23
|
+
history?: number;
|
|
24
|
+
auditLog?: number;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=retention.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.types.d.ts","sourceRoot":"","sources":["../../src/retention/retention.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzC,MAAM,WAAW,aAAa,CAAC,UAAU;IACvC,KAAK,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC9C;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,KAAK,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,OAAO,CAAC,EAAE,sBAAsB,CAAA;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,uBAAuB,CAAA;IAClC,yDAAyD;IACzD,UAAU,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.types.js","sourceRoot":"","sources":["../../src/retention/retention.types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modern-admin/queue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "BullMQ-based queue + cron module for Modern Admin (NestJS).",
|
|
5
5
|
"homepage": "https://github.com/modern-admin/modern-admin/tree/main/packages/queue#readme",
|
|
6
6
|
"keywords": [
|
|
@@ -44,6 +44,9 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@modern-admin/core": "^0.9.0"
|
|
49
|
+
},
|
|
47
50
|
"devDependencies": {
|
|
48
51
|
"@modern-admin/tsconfig": "0.4.0",
|
|
49
52
|
"@nestjs/bullmq": "^11.0.5",
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
DEFAULT_CRON_LOCK_TTL,
|
|
8
8
|
DEFAULT_CRON_WORKER_CONCURRENCY,
|
|
9
9
|
} from './cron.constants.js'
|
|
10
|
-
import
|
|
10
|
+
import { CronService } from './cron.service.js'
|
|
11
11
|
|
|
12
12
|
@Processor(CRON_QUEUE, { concurrency: DEFAULT_CRON_WORKER_CONCURRENCY })
|
|
13
13
|
export class CronProcessor extends WorkerHost {
|
package/src/index.ts
CHANGED
|
@@ -17,3 +17,16 @@ export {
|
|
|
17
17
|
type CronHandler,
|
|
18
18
|
type CronTaskDefinition,
|
|
19
19
|
} from './cron'
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
RetentionModule,
|
|
23
|
+
RetentionService,
|
|
24
|
+
RETENTION_OPTIONS,
|
|
25
|
+
DEFAULT_RETENTION_CRON,
|
|
26
|
+
SYSTEM_RETENTION_TASK,
|
|
27
|
+
type AuditLogRetentionTarget,
|
|
28
|
+
type HistoryRetentionTarget,
|
|
29
|
+
type PrunableStore,
|
|
30
|
+
type RetentionModuleOptions,
|
|
31
|
+
type RetentionRunResult,
|
|
32
|
+
} from './retention'
|
package/src/queue.module.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { type DynamicModule, Module } from '@nestjs/common'
|
|
|
2
2
|
import { BullModule } from '@nestjs/bullmq'
|
|
3
3
|
import type { QueueModuleOptions, QueueRootOptions } from './queue.types.js'
|
|
4
4
|
|
|
5
|
+
export const normalizeQueueConnection = (
|
|
6
|
+
connection: QueueRootOptions['connection'],
|
|
7
|
+
): object => typeof connection === 'string' ? { url: connection } : connection
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* BullMQ integration module for modern-admin NestJS applications.
|
|
7
11
|
*
|
|
@@ -30,7 +34,7 @@ export class QueueModule {
|
|
|
30
34
|
global: true,
|
|
31
35
|
imports: [
|
|
32
36
|
BullModule.forRoot({
|
|
33
|
-
connection: options.connection
|
|
37
|
+
connection: normalizeQueueConnection(options.connection),
|
|
34
38
|
defaultJobOptions: options.defaultJobOptions,
|
|
35
39
|
}),
|
|
36
40
|
],
|
|
@@ -65,7 +69,7 @@ export class QueueModule {
|
|
|
65
69
|
useFactory: async (...args: unknown[]) => {
|
|
66
70
|
const resolved = await opts.useFactory(...args)
|
|
67
71
|
return {
|
|
68
|
-
connection: resolved.connection
|
|
72
|
+
connection: normalizeQueueConnection(resolved.connection),
|
|
69
73
|
defaultJobOptions: resolved.defaultJobOptions,
|
|
70
74
|
}
|
|
71
75
|
},
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { RetentionModule } from './retention.module.js'
|
|
2
|
+
export { RetentionService } from './retention.service.js'
|
|
3
|
+
export { RETENTION_OPTIONS } from './retention.tokens.js'
|
|
4
|
+
export { DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK } from './retention.constants.js'
|
|
5
|
+
export type {
|
|
6
|
+
AuditLogRetentionTarget,
|
|
7
|
+
HistoryRetentionTarget,
|
|
8
|
+
PrunableStore,
|
|
9
|
+
RetentionModuleOptions,
|
|
10
|
+
RetentionRunResult,
|
|
11
|
+
} from './retention.types.js'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type DynamicModule, Module } from '@nestjs/common'
|
|
2
|
+
import { CronModule } from '../cron/cron.module.js'
|
|
3
|
+
import { RetentionService } from './retention.service.js'
|
|
4
|
+
import { RETENTION_OPTIONS } from './retention.tokens.js'
|
|
5
|
+
import type { RetentionModuleOptions } from './retention.types.js'
|
|
6
|
+
|
|
7
|
+
const assertBound = (name: string, value: number | undefined): void => {
|
|
8
|
+
if (value === undefined) return
|
|
9
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
|
|
10
|
+
throw new Error(`${name} must be a non-negative integer`)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const validateOptions = (options: RetentionModuleOptions): void => {
|
|
15
|
+
if (options.cron !== undefined && options.cron.trim().length === 0) {
|
|
16
|
+
throw new Error('retention cron must not be empty')
|
|
17
|
+
}
|
|
18
|
+
assertBound('history.keepLast', options.history?.keepLast)
|
|
19
|
+
assertBound('history.keepDays', options.history?.keepDays)
|
|
20
|
+
assertBound('auditLog.keepLast', options.auditLog?.keepLast)
|
|
21
|
+
assertBound('auditLog.keepDays', options.auditLog?.keepDays)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Schedules history and action-log pruning as a durable BullMQ cron task.
|
|
26
|
+
* Requires `QueueModule.forRoot()` in the host application's root module.
|
|
27
|
+
*/
|
|
28
|
+
@Module({})
|
|
29
|
+
export class RetentionModule {
|
|
30
|
+
static forRoot(options: RetentionModuleOptions): DynamicModule {
|
|
31
|
+
validateOptions(options)
|
|
32
|
+
return {
|
|
33
|
+
module: RetentionModule,
|
|
34
|
+
imports: [CronModule],
|
|
35
|
+
providers: [
|
|
36
|
+
{ provide: RETENTION_OPTIONS, useValue: options },
|
|
37
|
+
RetentionService,
|
|
38
|
+
],
|
|
39
|
+
exports: [RetentionService],
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Inject, Injectable, type OnModuleInit } from '@nestjs/common'
|
|
2
|
+
import type { ActionLogRetention, HistoryRetention } from '@modern-admin/core'
|
|
3
|
+
import { CronService } from '../cron/cron.service.js'
|
|
4
|
+
import { DEFAULT_RETENTION_CRON, SYSTEM_RETENTION_TASK } from './retention.constants.js'
|
|
5
|
+
import { RETENTION_OPTIONS } from './retention.tokens.js'
|
|
6
|
+
import type {
|
|
7
|
+
AuditLogRetentionTarget,
|
|
8
|
+
HistoryRetentionTarget,
|
|
9
|
+
RetentionModuleOptions,
|
|
10
|
+
RetentionRunResult,
|
|
11
|
+
} from './retention.types.js'
|
|
12
|
+
|
|
13
|
+
const hasBounds = (retention: { keepLast?: number; keepDays?: number }): boolean =>
|
|
14
|
+
retention.keepLast !== undefined || retention.keepDays !== undefined
|
|
15
|
+
|
|
16
|
+
@Injectable()
|
|
17
|
+
export class RetentionService implements OnModuleInit {
|
|
18
|
+
constructor(
|
|
19
|
+
@Inject(RETENTION_OPTIONS) private readonly options: RetentionModuleOptions,
|
|
20
|
+
private readonly cron: CronService,
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
onModuleInit(): void {
|
|
24
|
+
if (!this.hasWork()) return
|
|
25
|
+
|
|
26
|
+
this.cron.register({
|
|
27
|
+
name: SYSTEM_RETENTION_TASK,
|
|
28
|
+
cron: this.options.cron ?? DEFAULT_RETENTION_CRON,
|
|
29
|
+
skipIfRunning: true,
|
|
30
|
+
opts: {
|
|
31
|
+
attempts: 3,
|
|
32
|
+
backoff: { type: 'exponential', delay: 1_000 },
|
|
33
|
+
...this.options.jobOptions,
|
|
34
|
+
},
|
|
35
|
+
handler: () => this.run(),
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Execute every configured retention target. Called by the BullMQ worker. */
|
|
40
|
+
async run(): Promise<RetentionRunResult> {
|
|
41
|
+
const result: RetentionRunResult = {}
|
|
42
|
+
const failures: unknown[] = []
|
|
43
|
+
|
|
44
|
+
if (this.options.history && hasBounds(this.options.history)) {
|
|
45
|
+
try {
|
|
46
|
+
result.history = await this.pruneHistory(this.options.history)
|
|
47
|
+
} catch (err: unknown) {
|
|
48
|
+
failures.push(err)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (this.options.auditLog && hasBounds(this.options.auditLog)) {
|
|
52
|
+
try {
|
|
53
|
+
result.auditLog = await this.pruneAuditLog(this.options.auditLog)
|
|
54
|
+
} catch (err: unknown) {
|
|
55
|
+
failures.push(err)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (failures.length === 1) {
|
|
60
|
+
throw failures[0]
|
|
61
|
+
}
|
|
62
|
+
if (failures.length > 1) {
|
|
63
|
+
throw new AggregateError(failures, 'Multiple retention targets failed')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private hasWork(): boolean {
|
|
70
|
+
return Boolean(
|
|
71
|
+
(this.options.history && hasBounds(this.options.history))
|
|
72
|
+
|| (this.options.auditLog && hasBounds(this.options.auditLog)),
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private pruneHistory(target: HistoryRetentionTarget): Promise<number> {
|
|
77
|
+
const retention: HistoryRetention = {
|
|
78
|
+
...(target.keepLast !== undefined ? { keepLast: target.keepLast } : {}),
|
|
79
|
+
...(target.keepDays !== undefined ? { keepDays: target.keepDays } : {}),
|
|
80
|
+
}
|
|
81
|
+
return target.store.prune(retention)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private pruneAuditLog(target: AuditLogRetentionTarget): Promise<number> {
|
|
85
|
+
const retention: ActionLogRetention = {
|
|
86
|
+
...(target.keepLast !== undefined ? { keepLast: target.keepLast } : {}),
|
|
87
|
+
...(target.keepDays !== undefined ? { keepDays: target.keepDays } : {}),
|
|
88
|
+
}
|
|
89
|
+
return target.store.prune(retention)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const RETENTION_OPTIONS = Symbol.for('@modern-admin/queue:RetentionOptions')
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ActionLogRetention, HistoryRetention } from '@modern-admin/core'
|
|
2
|
+
import type { JobsOptions } from 'bullmq'
|
|
3
|
+
|
|
4
|
+
export interface PrunableStore<TRetention> {
|
|
5
|
+
prune(retention: TRetention): Promise<number>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface HistoryRetentionTarget extends HistoryRetention {
|
|
9
|
+
store: PrunableStore<HistoryRetention>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface AuditLogRetentionTarget extends ActionLogRetention {
|
|
13
|
+
store: PrunableStore<ActionLogRetention>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface RetentionModuleOptions {
|
|
17
|
+
/** BullMQ cron expression. Defaults to every day at 03:00 UTC. */
|
|
18
|
+
cron?: string
|
|
19
|
+
/** Revision-history retention. `keepLast` is evaluated per record. */
|
|
20
|
+
history?: HistoryRetentionTarget
|
|
21
|
+
/** Action-log retention. `keepLast` is evaluated globally. */
|
|
22
|
+
auditLog?: AuditLogRetentionTarget
|
|
23
|
+
/** BullMQ options for each scheduled maintenance job. */
|
|
24
|
+
jobOptions?: Omit<JobsOptions, 'repeat'>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface RetentionRunResult {
|
|
28
|
+
history?: number
|
|
29
|
+
auditLog?: number
|
|
30
|
+
}
|