@nest-toolbox/typeorm-audit-log 1.8.1

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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/audit-context.d.ts +67 -0
  4. package/dist/audit-context.js +96 -0
  5. package/dist/audit-context.js.map +1 -0
  6. package/dist/audit-context.middleware.d.ts +76 -0
  7. package/dist/audit-context.middleware.js +91 -0
  8. package/dist/audit-context.middleware.js.map +1 -0
  9. package/dist/audit-log.entity.d.ts +56 -0
  10. package/dist/audit-log.entity.js +89 -0
  11. package/dist/audit-log.entity.js.map +1 -0
  12. package/dist/audit-log.module.d.ts +56 -0
  13. package/dist/audit-log.module.js +130 -0
  14. package/dist/audit-log.module.js.map +1 -0
  15. package/dist/audit-log.service.d.ts +43 -0
  16. package/dist/audit-log.service.js +177 -0
  17. package/dist/audit-log.service.js.map +1 -0
  18. package/dist/audit-log.subscriber.d.ts +66 -0
  19. package/dist/audit-log.subscriber.js +135 -0
  20. package/dist/audit-log.subscriber.js.map +1 -0
  21. package/dist/constants.d.ts +32 -0
  22. package/dist/constants.js +49 -0
  23. package/dist/constants.js.map +1 -0
  24. package/dist/decorators.d.ts +109 -0
  25. package/dist/decorators.js +161 -0
  26. package/dist/decorators.js.map +1 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.js +31 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/tsconfig.build.tsbuildinfo +1 -0
  31. package/dist/types.d.ts +161 -0
  32. package/dist/types.js +16 -0
  33. package/dist/types.js.map +1 -0
  34. package/dist/utils/diff.d.ts +16 -0
  35. package/dist/utils/diff.js +142 -0
  36. package/dist/utils/diff.js.map +1 -0
  37. package/dist/utils/mask.d.ts +15 -0
  38. package/dist/utils/mask.js +69 -0
  39. package/dist/utils/mask.js.map +1 -0
  40. package/package.json +63 -0
@@ -0,0 +1,89 @@
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.AuditLog = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ /**
15
+ * Entity for storing audit log entries.
16
+ * Tracks all changes to entities decorated with @Auditable().
17
+ */
18
+ let AuditLog = class AuditLog {
19
+ };
20
+ exports.AuditLog = AuditLog;
21
+ __decorate([
22
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
23
+ __metadata("design:type", String)
24
+ ], AuditLog.prototype, "id", void 0);
25
+ __decorate([
26
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255 }),
27
+ __metadata("design:type", String)
28
+ ], AuditLog.prototype, "entityName", void 0);
29
+ __decorate([
30
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255 }),
31
+ __metadata("design:type", String)
32
+ ], AuditLog.prototype, "entityId", void 0);
33
+ __decorate([
34
+ (0, typeorm_1.Column)({
35
+ type: 'varchar',
36
+ length: 10,
37
+ }),
38
+ __metadata("design:type", String)
39
+ ], AuditLog.prototype, "action", void 0);
40
+ __decorate([
41
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
42
+ __metadata("design:type", Object)
43
+ ], AuditLog.prototype, "userId", void 0);
44
+ __decorate([
45
+ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }),
46
+ __metadata("design:type", Object)
47
+ ], AuditLog.prototype, "userName", void 0);
48
+ __decorate([
49
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true })
50
+ // biome-ignore lint/suspicious/noExplicitAny: values can be any type
51
+ ,
52
+ __metadata("design:type", Object)
53
+ ], AuditLog.prototype, "oldValues", void 0);
54
+ __decorate([
55
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true })
56
+ // biome-ignore lint/suspicious/noExplicitAny: values can be any type
57
+ ,
58
+ __metadata("design:type", Object)
59
+ ], AuditLog.prototype, "newValues", void 0);
60
+ __decorate([
61
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
62
+ __metadata("design:type", Object)
63
+ ], AuditLog.prototype, "diff", void 0);
64
+ __decorate([
65
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true })
66
+ // biome-ignore lint/suspicious/noExplicitAny: metadata can contain any value
67
+ ,
68
+ __metadata("design:type", Object)
69
+ ], AuditLog.prototype, "metadata", void 0);
70
+ __decorate([
71
+ (0, typeorm_1.Column)({ type: 'varchar', length: 45, nullable: true }),
72
+ __metadata("design:type", Object)
73
+ ], AuditLog.prototype, "ip", void 0);
74
+ __decorate([
75
+ (0, typeorm_1.Column)({ type: 'varchar', length: 500, nullable: true }),
76
+ __metadata("design:type", Object)
77
+ ], AuditLog.prototype, "userAgent", void 0);
78
+ __decorate([
79
+ (0, typeorm_1.CreateDateColumn)(),
80
+ __metadata("design:type", Date)
81
+ ], AuditLog.prototype, "timestamp", void 0);
82
+ exports.AuditLog = AuditLog = __decorate([
83
+ (0, typeorm_1.Entity)('audit_logs'),
84
+ (0, typeorm_1.Index)(['entityName', 'entityId']),
85
+ (0, typeorm_1.Index)(['userId']),
86
+ (0, typeorm_1.Index)(['timestamp']),
87
+ (0, typeorm_1.Index)(['entityName', 'timestamp'])
88
+ ], AuditLog);
89
+ //# sourceMappingURL=audit-log.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.entity.js","sourceRoot":"","sources":["../src/audit-log.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0F;AAG1F;;;GAGG;AAMI,IAAM,QAAQ,GAAd,MAAM,QAAQ;CAiFpB,CAAA;AAjFY,4BAAQ;AAEnB;IADC,IAAA,gCAAsB,EAAC,MAAM,CAAC;;oCACnB;AAMZ;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;4CACrB;AAMpB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;0CACvB;AASlB;IAJC,IAAA,gBAAM,EAAC;QACN,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,EAAE;KACX,CAAC;;wCACmB;AAMrB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;wCAClC;AAMvB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;0CAChC;AAOzB;IAFC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,qEAAqE;;;2CAC9B;AAOvC;IAFC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,qEAAqE;;;2CAC9B;AAMvC;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;sCAChB;AAO1B;IAFC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC1C,6EAA6E;;;0CACvC;AAMtC;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;oCACrC;AAMnB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;2CAC/B;AAM1B;IADC,IAAA,0BAAgB,GAAE;8BACP,IAAI;2CAAC;mBAhFN,QAAQ;IALpB,IAAA,gBAAM,EAAC,YAAY,CAAC;IACpB,IAAA,eAAK,EAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACjC,IAAA,eAAK,EAAC,CAAC,QAAQ,CAAC,CAAC;IACjB,IAAA,eAAK,EAAC,CAAC,WAAW,CAAC,CAAC;IACpB,IAAA,eAAK,EAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;GACtB,QAAQ,CAiFpB"}
@@ -0,0 +1,56 @@
1
+ import { type DynamicModule, type OnModuleInit } from '@nestjs/common';
2
+ import type { DataSource } from 'typeorm';
3
+ import { AuditLogService } from './audit-log.service';
4
+ import { AuditLogSubscriber } from './audit-log.subscriber';
5
+ import type { AuditLogModuleAsyncOptions, AuditLogModuleOptions } from './types';
6
+ /**
7
+ * AuditLogModule provides automatic audit logging for TypeORM entities.
8
+ *
9
+ * @example Basic usage
10
+ * ```typescript
11
+ * @Module({
12
+ * imports: [
13
+ * TypeOrmModule.forRoot({...}),
14
+ * AuditLogModule.forRoot({
15
+ * retentionDays: 90,
16
+ * excludeFields: ['password', 'token'],
17
+ * }),
18
+ * ],
19
+ * })
20
+ * export class AppModule implements NestModule {
21
+ * configure(consumer: MiddlewareConsumer) {
22
+ * consumer.apply(AuditContextMiddleware).forRoutes('*');
23
+ * }
24
+ * }
25
+ * ```
26
+ *
27
+ * @example Async configuration
28
+ * ```typescript
29
+ * AuditLogModule.forRootAsync({
30
+ * imports: [ConfigModule],
31
+ * useFactory: (config: ConfigService) => ({
32
+ * retentionDays: config.get('AUDIT_RETENTION_DAYS'),
33
+ * async: config.get('AUDIT_ASYNC') === 'true',
34
+ * }),
35
+ * inject: [ConfigService],
36
+ * })
37
+ * ```
38
+ */
39
+ export declare class AuditLogModule implements OnModuleInit {
40
+ private readonly dataSource;
41
+ private readonly subscriber;
42
+ private readonly auditLogService;
43
+ constructor(dataSource: DataSource, subscriber: AuditLogSubscriber, auditLogService: AuditLogService);
44
+ /**
45
+ * Initialize the module: register subscriber with DataSource and inject service.
46
+ */
47
+ onModuleInit(): void;
48
+ /**
49
+ * Configure the module with static options.
50
+ */
51
+ static forRoot(options?: AuditLogModuleOptions): DynamicModule;
52
+ /**
53
+ * Configure the module with async options (factory, useClass, useExisting).
54
+ */
55
+ static forRootAsync(options: AuditLogModuleAsyncOptions): DynamicModule;
56
+ }
@@ -0,0 +1,130 @@
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
+ var AuditLogModule_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.AuditLogModule = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const typeorm_1 = require("@nestjs/typeorm");
16
+ const audit_log_entity_1 = require("./audit-log.entity");
17
+ const audit_log_service_1 = require("./audit-log.service");
18
+ const audit_log_subscriber_1 = require("./audit-log.subscriber");
19
+ const constants_1 = require("./constants");
20
+ /**
21
+ * Default module options.
22
+ */
23
+ const DEFAULT_OPTIONS = {
24
+ storage: 'database',
25
+ retentionDays: 0,
26
+ excludeFields: [],
27
+ excludeEntities: [],
28
+ async: false,
29
+ batchSize: 1,
30
+ };
31
+ /**
32
+ * AuditLogModule provides automatic audit logging for TypeORM entities.
33
+ *
34
+ * @example Basic usage
35
+ * ```typescript
36
+ * @Module({
37
+ * imports: [
38
+ * TypeOrmModule.forRoot({...}),
39
+ * AuditLogModule.forRoot({
40
+ * retentionDays: 90,
41
+ * excludeFields: ['password', 'token'],
42
+ * }),
43
+ * ],
44
+ * })
45
+ * export class AppModule implements NestModule {
46
+ * configure(consumer: MiddlewareConsumer) {
47
+ * consumer.apply(AuditContextMiddleware).forRoutes('*');
48
+ * }
49
+ * }
50
+ * ```
51
+ *
52
+ * @example Async configuration
53
+ * ```typescript
54
+ * AuditLogModule.forRootAsync({
55
+ * imports: [ConfigModule],
56
+ * useFactory: (config: ConfigService) => ({
57
+ * retentionDays: config.get('AUDIT_RETENTION_DAYS'),
58
+ * async: config.get('AUDIT_ASYNC') === 'true',
59
+ * }),
60
+ * inject: [ConfigService],
61
+ * })
62
+ * ```
63
+ */
64
+ let AuditLogModule = AuditLogModule_1 = class AuditLogModule {
65
+ constructor(dataSource, subscriber, auditLogService) {
66
+ this.dataSource = dataSource;
67
+ this.subscriber = subscriber;
68
+ this.auditLogService = auditLogService;
69
+ }
70
+ /**
71
+ * Initialize the module: register subscriber with DataSource and inject service.
72
+ */
73
+ onModuleInit() {
74
+ // Register the subscriber with TypeORM DataSource
75
+ this.subscriber.registerWithDataSource(this.dataSource);
76
+ // Inject the service into the subscriber
77
+ this.subscriber.setAuditLogService(this.auditLogService);
78
+ }
79
+ /**
80
+ * Configure the module with static options.
81
+ */
82
+ static forRoot(options = {}) {
83
+ const mergedOptions = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
84
+ return {
85
+ module: AuditLogModule_1,
86
+ imports: [typeorm_1.TypeOrmModule.forFeature([audit_log_entity_1.AuditLog])],
87
+ providers: [
88
+ {
89
+ provide: constants_1.AUDIT_LOG_OPTIONS,
90
+ useValue: mergedOptions,
91
+ },
92
+ audit_log_service_1.AuditLogService,
93
+ audit_log_subscriber_1.AuditLogSubscriber,
94
+ ],
95
+ exports: [audit_log_service_1.AuditLogService, audit_log_subscriber_1.AuditLogSubscriber],
96
+ global: true,
97
+ };
98
+ }
99
+ /**
100
+ * Configure the module with async options (factory, useClass, useExisting).
101
+ */
102
+ static forRootAsync(options) {
103
+ var _a, _b;
104
+ return {
105
+ module: AuditLogModule_1,
106
+ imports: [...((_a = options.imports) !== null && _a !== void 0 ? _a : []), typeorm_1.TypeOrmModule.forFeature([audit_log_entity_1.AuditLog])],
107
+ providers: [
108
+ {
109
+ provide: constants_1.AUDIT_LOG_OPTIONS,
110
+ useFactory: async (...args) => {
111
+ const config = options.useFactory ? await options.useFactory(...args) : {};
112
+ return Object.assign(Object.assign({}, DEFAULT_OPTIONS), config);
113
+ },
114
+ inject: (_b = options.inject) !== null && _b !== void 0 ? _b : [],
115
+ },
116
+ audit_log_service_1.AuditLogService,
117
+ audit_log_subscriber_1.AuditLogSubscriber,
118
+ ],
119
+ exports: [audit_log_service_1.AuditLogService, audit_log_subscriber_1.AuditLogSubscriber],
120
+ global: true,
121
+ };
122
+ }
123
+ };
124
+ exports.AuditLogModule = AuditLogModule;
125
+ exports.AuditLogModule = AuditLogModule = AuditLogModule_1 = __decorate([
126
+ (0, common_1.Module)({}),
127
+ __metadata("design:paramtypes", [Function, audit_log_subscriber_1.AuditLogSubscriber,
128
+ audit_log_service_1.AuditLogService])
129
+ ], AuditLogModule);
130
+ //# sourceMappingURL=audit-log.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.module.js","sourceRoot":"","sources":["../src/audit-log.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAA+E;AAC/E,6CAAgD;AAEhD,yDAA8C;AAC9C,2DAAsD;AACtD,iEAA4D;AAC5D,2CAAgD;AAGhD;;GAEG;AACH,MAAM,eAAe,GAA0B;IAC7C,OAAO,EAAE,UAAU;IACnB,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,EAAE;IACjB,eAAe,EAAE,EAAE;IACnB,KAAK,EAAE,KAAK;IACZ,SAAS,EAAE,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEI,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,YACmB,UAAsB,EACtB,UAA8B,EAC9B,eAAgC;QAFhC,eAAU,GAAV,UAAU,CAAY;QACtB,eAAU,GAAV,UAAU,CAAoB;QAC9B,oBAAe,GAAf,eAAe,CAAiB;IAChD,CAAC;IAEJ;;OAEG;IACH,YAAY;QACV,kDAAkD;QAClD,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxD,yCAAyC;QACzC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,UAAiC,EAAE;QAChD,MAAM,aAAa,mCAAQ,eAAe,GAAK,OAAO,CAAE,CAAC;QAEzD,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,OAAO,EAAE,CAAC,uBAAa,CAAC,UAAU,CAAC,CAAC,2BAAQ,CAAC,CAAC,CAAC;YAC/C,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,6BAAiB;oBAC1B,QAAQ,EAAE,aAAa;iBACxB;gBACD,mCAAe;gBACf,yCAAkB;aACnB;YACD,OAAO,EAAE,CAAC,mCAAe,EAAE,yCAAkB,CAAC;YAC9C,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,OAAmC;;QACrD,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,OAAO,EAAE,CAAC,GAAG,CAAC,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE,CAAC,EAAE,uBAAa,CAAC,UAAU,CAAC,CAAC,2BAAQ,CAAC,CAAC,CAAC;YAC3E,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,6BAAiB;oBAC1B,UAAU,EAAE,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;wBACvC,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC3E,uCAAY,eAAe,GAAK,MAAM,EAAG;oBAC3C,CAAC;oBACD,MAAM,EAAE,MAAA,OAAO,CAAC,MAAM,mCAAI,EAAE;iBAC7B;gBACD,mCAAe;gBACf,yCAAkB;aACnB;YACD,OAAO,EAAE,CAAC,mCAAe,EAAE,yCAAkB,CAAC;YAC9C,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;CACF,CAAA;AA9DY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,eAAM,EAAC,EAAE,CAAC;+CAIsB,yCAAkB;QACb,mCAAe;GAJxC,cAAc,CA8D1B"}
@@ -0,0 +1,43 @@
1
+ import type { Repository } from 'typeorm';
2
+ import { AuditLog } from './audit-log.entity';
3
+ import type { IAuditLogService } from './audit-log.subscriber';
4
+ import type { AuditLogModuleOptions, FindAllOptions, FindByEntityOptions, FindByUserOptions, LogParams, PaginatedResult } from './types';
5
+ /**
6
+ * Service for logging and querying audit entries.
7
+ * Captures entity changes with user attribution, diff calculation,
8
+ * and request context (IP, user agent, metadata).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Query audit history for an entity
13
+ * const history = await auditLogService.findByEntity('User', '123');
14
+ *
15
+ * // Query changes made by a specific user
16
+ * const userChanges = await auditLogService.findByUser('user-456', {
17
+ * since: new Date('2024-01-01'),
18
+ * });
19
+ * ```
20
+ */
21
+ export declare class AuditLogService implements IAuditLogService {
22
+ private readonly repo;
23
+ private readonly options;
24
+ constructor(repo: Repository<AuditLog>, options: AuditLogModuleOptions);
25
+ /**
26
+ * Log an audit entry for an entity change.
27
+ * Automatically captures user context from AsyncLocalStorage.
28
+ * Applies @AuditIgnore and @AuditMask decorators from the entity.
29
+ */
30
+ log(params: LogParams): Promise<void>;
31
+ /**
32
+ * Find audit logs for a specific entity.
33
+ */
34
+ findByEntity(entityName: string, entityId: string, options?: FindByEntityOptions): Promise<AuditLog[]>;
35
+ /**
36
+ * Find audit logs by user ID.
37
+ */
38
+ findByUser(userId: string, options?: FindByUserOptions): Promise<AuditLog[]>;
39
+ /**
40
+ * Find all audit logs with optional filters and pagination.
41
+ */
42
+ findAll(options?: FindAllOptions): Promise<PaginatedResult<AuditLog>>;
43
+ }
@@ -0,0 +1,177 @@
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
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AuditLogService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("@nestjs/typeorm");
18
+ const audit_context_1 = require("./audit-context");
19
+ const audit_log_entity_1 = require("./audit-log.entity");
20
+ const constants_1 = require("./constants");
21
+ const diff_1 = require("./utils/diff");
22
+ const mask_1 = require("./utils/mask");
23
+ /**
24
+ * Service for logging and querying audit entries.
25
+ * Captures entity changes with user attribution, diff calculation,
26
+ * and request context (IP, user agent, metadata).
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Query audit history for an entity
31
+ * const history = await auditLogService.findByEntity('User', '123');
32
+ *
33
+ * // Query changes made by a specific user
34
+ * const userChanges = await auditLogService.findByUser('user-456', {
35
+ * since: new Date('2024-01-01'),
36
+ * });
37
+ * ```
38
+ */
39
+ let AuditLogService = class AuditLogService {
40
+ constructor(repo, options) {
41
+ this.repo = repo;
42
+ this.options = options;
43
+ }
44
+ /**
45
+ * Log an audit entry for an entity change.
46
+ * Automatically captures user context from AsyncLocalStorage.
47
+ * Applies @AuditIgnore and @AuditMask decorators from the entity.
48
+ */
49
+ async log(params) {
50
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
51
+ const context = (0, audit_context_1.getAuditContext)();
52
+ // Get entity class for decorator metadata
53
+ const entityClass = (_b = (_a = params.entity) === null || _a === void 0 ? void 0 : _a.constructor) !== null && _b !== void 0 ? _b : null;
54
+ // Get all excluded fields (global + @AuditIgnore)
55
+ const excludeFields = (0, mask_1.getAllExcludedFields)(entityClass, (_c = this.options.excludeFields) !== null && _c !== void 0 ? _c : []);
56
+ // Calculate diff between old and new values using deep-diff
57
+ const diff = (0, diff_1.calculateDiff)(params.oldValues, params.entity, excludeFields);
58
+ // Apply masking and exclusions to values
59
+ const oldValues = (0, mask_1.applyMaskAndExclusions)(params.oldValues, entityClass, (_d = this.options.excludeFields) !== null && _d !== void 0 ? _d : []);
60
+ const newValues = (0, mask_1.applyMaskAndExclusions)(params.entity, entityClass, (_e = this.options.excludeFields) !== null && _e !== void 0 ? _e : []);
61
+ // Create audit log entry
62
+ const entry = this.repo.create({
63
+ entityName: params.entityName,
64
+ entityId: params.entityId,
65
+ action: params.action,
66
+ userId: (_f = context === null || context === void 0 ? void 0 : context.userId) !== null && _f !== void 0 ? _f : null,
67
+ userName: (_g = context === null || context === void 0 ? void 0 : context.userName) !== null && _g !== void 0 ? _g : null,
68
+ oldValues,
69
+ newValues,
70
+ diff,
71
+ ip: (_h = context === null || context === void 0 ? void 0 : context.ip) !== null && _h !== void 0 ? _h : null,
72
+ userAgent: (_j = context === null || context === void 0 ? void 0 : context.userAgent) !== null && _j !== void 0 ? _j : null,
73
+ metadata: (_k = context === null || context === void 0 ? void 0 : context.metadata) !== null && _k !== void 0 ? _k : null,
74
+ });
75
+ // Save the audit log
76
+ if (this.options.async) {
77
+ // Fire and forget for async mode
78
+ this.repo.save(entry).catch((error) => {
79
+ console.error('[AuditLogService] Failed to save audit log:', error);
80
+ });
81
+ }
82
+ else {
83
+ await this.repo.save(entry);
84
+ }
85
+ }
86
+ /**
87
+ * Find audit logs for a specific entity.
88
+ */
89
+ async findByEntity(entityName, entityId, options) {
90
+ const query = this.repo
91
+ .createQueryBuilder('audit')
92
+ .where('audit.entityName = :entityName', { entityName })
93
+ .andWhere('audit.entityId = :entityId', { entityId });
94
+ if (options === null || options === void 0 ? void 0 : options.since) {
95
+ query.andWhere('audit.timestamp >= :since', { since: options.since });
96
+ }
97
+ if (options === null || options === void 0 ? void 0 : options.until) {
98
+ query.andWhere('audit.timestamp <= :until', { until: options.until });
99
+ }
100
+ if (options === null || options === void 0 ? void 0 : options.action) {
101
+ query.andWhere('audit.action = :action', { action: options.action });
102
+ }
103
+ query.orderBy('audit.timestamp', 'DESC');
104
+ if (options === null || options === void 0 ? void 0 : options.limit) {
105
+ query.take(options.limit);
106
+ }
107
+ return query.getMany();
108
+ }
109
+ /**
110
+ * Find audit logs by user ID.
111
+ */
112
+ async findByUser(userId, options) {
113
+ const query = this.repo.createQueryBuilder('audit').where('audit.userId = :userId', { userId });
114
+ if (options === null || options === void 0 ? void 0 : options.since) {
115
+ query.andWhere('audit.timestamp >= :since', { since: options.since });
116
+ }
117
+ if (options === null || options === void 0 ? void 0 : options.until) {
118
+ query.andWhere('audit.timestamp <= :until', { until: options.until });
119
+ }
120
+ if (options === null || options === void 0 ? void 0 : options.entityName) {
121
+ query.andWhere('audit.entityName = :entityName', { entityName: options.entityName });
122
+ }
123
+ if (options === null || options === void 0 ? void 0 : options.action) {
124
+ query.andWhere('audit.action = :action', { action: options.action });
125
+ }
126
+ query.orderBy('audit.timestamp', 'DESC');
127
+ if (options === null || options === void 0 ? void 0 : options.limit) {
128
+ query.take(options.limit);
129
+ }
130
+ return query.getMany();
131
+ }
132
+ /**
133
+ * Find all audit logs with optional filters and pagination.
134
+ */
135
+ async findAll(options) {
136
+ var _a, _b;
137
+ const page = (_a = options === null || options === void 0 ? void 0 : options.page) !== null && _a !== void 0 ? _a : 1;
138
+ const limit = (_b = options === null || options === void 0 ? void 0 : options.limit) !== null && _b !== void 0 ? _b : 50;
139
+ const skip = (page - 1) * limit;
140
+ const query = this.repo.createQueryBuilder('audit');
141
+ if (options === null || options === void 0 ? void 0 : options.since) {
142
+ query.andWhere('audit.timestamp >= :since', { since: options.since });
143
+ }
144
+ if (options === null || options === void 0 ? void 0 : options.until) {
145
+ query.andWhere('audit.timestamp <= :until', { until: options.until });
146
+ }
147
+ if (options === null || options === void 0 ? void 0 : options.entityName) {
148
+ query.andWhere('audit.entityName = :entityName', { entityName: options.entityName });
149
+ }
150
+ if (options === null || options === void 0 ? void 0 : options.entityId) {
151
+ query.andWhere('audit.entityId = :entityId', { entityId: options.entityId });
152
+ }
153
+ if (options === null || options === void 0 ? void 0 : options.userId) {
154
+ query.andWhere('audit.userId = :userId', { userId: options.userId });
155
+ }
156
+ if (options === null || options === void 0 ? void 0 : options.action) {
157
+ query.andWhere('audit.action = :action', { action: options.action });
158
+ }
159
+ query.orderBy('audit.timestamp', 'DESC');
160
+ const [items, total] = await query.skip(skip).take(limit).getManyAndCount();
161
+ return {
162
+ items,
163
+ total,
164
+ page,
165
+ limit,
166
+ totalPages: Math.ceil(total / limit),
167
+ };
168
+ }
169
+ };
170
+ exports.AuditLogService = AuditLogService;
171
+ exports.AuditLogService = AuditLogService = __decorate([
172
+ (0, common_1.Injectable)(),
173
+ __param(0, (0, typeorm_1.InjectRepository)(audit_log_entity_1.AuditLog)),
174
+ __param(1, (0, common_1.Inject)(constants_1.AUDIT_LOG_OPTIONS)),
175
+ __metadata("design:paramtypes", [Function, Object])
176
+ ], AuditLogService);
177
+ //# sourceMappingURL=audit-log.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.service.js","sourceRoot":"","sources":["../src/audit-log.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import type { DataSource, EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent } from 'typeorm';
2
+ import { type LogParams } from './types';
3
+ /**
4
+ * Interface for the audit log service that the subscriber depends on.
5
+ * Allows for loose coupling and easier testing.
6
+ */
7
+ export interface IAuditLogService {
8
+ log(params: LogParams): Promise<void>;
9
+ }
10
+ /**
11
+ * TypeORM event subscriber that captures entity changes and logs them.
12
+ * Automatically detects entities decorated with @Auditable() and creates
13
+ * audit log entries for INSERT, UPDATE, and DELETE operations.
14
+ *
15
+ * This subscriber is designed to be instantiated by NestJS DI and then
16
+ * registered with the TypeORM DataSource.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // In your module
21
+ * @Module({
22
+ * providers: [
23
+ * {
24
+ * provide: AuditLogSubscriber,
25
+ * useFactory: (dataSource: DataSource, auditLogService: AuditLogService) => {
26
+ * const subscriber = new AuditLogSubscriber(auditLogService);
27
+ * dataSource.subscribers.push(subscriber);
28
+ * return subscriber;
29
+ * },
30
+ * inject: [DataSource, AuditLogService],
31
+ * },
32
+ * ],
33
+ * })
34
+ * ```
35
+ */
36
+ export declare class AuditLogSubscriber implements EntitySubscriberInterface {
37
+ private auditLogService;
38
+ /**
39
+ * Set the audit log service. Called during module initialization.
40
+ */
41
+ setAuditLogService(service: IAuditLogService): void;
42
+ /**
43
+ * Register this subscriber with a TypeORM DataSource.
44
+ */
45
+ registerWithDataSource(dataSource: DataSource): void;
46
+ /**
47
+ * Handle entity insertion events.
48
+ */
49
+ afterInsert(event: InsertEvent<unknown>): void;
50
+ /**
51
+ * Handle entity update events.
52
+ */
53
+ afterUpdate(event: UpdateEvent<unknown>): void;
54
+ /**
55
+ * Handle entity removal events.
56
+ */
57
+ afterRemove(event: RemoveEvent<unknown>): void;
58
+ /**
59
+ * Common handler for all entity events.
60
+ */
61
+ private handleEvent;
62
+ /**
63
+ * Extract the entity ID from the event or entity.
64
+ */
65
+ private getEntityId;
66
+ }