@nest-util/nest-crud 0.0.3 → 1.0.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.
Files changed (48) hide show
  1. package/README.md +13 -3
  2. package/dist/index.d.ts +11 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +11 -4
  5. package/dist/lib/controllers/nest-crud.controller.d.ts +2 -1
  6. package/dist/lib/controllers/nest-crud.controller.d.ts.map +1 -1
  7. package/dist/lib/controllers/nest-crud.controller.js +41 -5
  8. package/dist/lib/decorators/audit-log.decorator.d.ts +7 -0
  9. package/dist/lib/decorators/audit-log.decorator.d.ts.map +1 -0
  10. package/dist/lib/decorators/audit-log.decorator.js +7 -0
  11. package/dist/lib/dtos/cursor-pagination.dto.d.ts +6 -0
  12. package/dist/lib/dtos/cursor-pagination.dto.d.ts.map +1 -0
  13. package/dist/lib/dtos/cursor-pagination.dto.js +47 -0
  14. package/dist/lib/dtos/list-audit-logs.dto.d.ts +8 -0
  15. package/dist/lib/dtos/list-audit-logs.dto.d.ts.map +1 -0
  16. package/dist/lib/dtos/list-audit-logs.dto.js +65 -0
  17. package/dist/lib/entities/audit-log.entity.d.ts +13 -0
  18. package/dist/lib/entities/audit-log.entity.d.ts.map +1 -0
  19. package/dist/lib/entities/audit-log.entity.js +58 -0
  20. package/dist/lib/helpers/cursor-pagination.helper.d.ts +9 -0
  21. package/dist/lib/helpers/cursor-pagination.helper.d.ts.map +1 -0
  22. package/dist/lib/helpers/cursor-pagination.helper.js +93 -0
  23. package/dist/lib/interceptors/audit-log.interceptor.d.ts +12 -0
  24. package/dist/lib/interceptors/audit-log.interceptor.d.ts.map +1 -0
  25. package/dist/lib/interceptors/audit-log.interceptor.js +72 -0
  26. package/dist/lib/interfaces/audit-log.interface.d.ts +11 -0
  27. package/dist/lib/interfaces/audit-log.interface.d.ts.map +1 -0
  28. package/dist/lib/interfaces/audit-log.interface.js +2 -0
  29. package/dist/lib/interfaces/crud.interface.d.ts +16 -1
  30. package/dist/lib/interfaces/crud.interface.d.ts.map +1 -1
  31. package/dist/lib/interfaces/cursor-strategy.interface.d.ts +30 -0
  32. package/dist/lib/interfaces/cursor-strategy.interface.d.ts.map +1 -0
  33. package/dist/lib/interfaces/cursor-strategy.interface.js +2 -0
  34. package/dist/lib/interfaces/find-mine.interface.d.ts +6 -0
  35. package/dist/lib/interfaces/find-mine.interface.d.ts.map +1 -0
  36. package/dist/lib/interfaces/find-mine.interface.js +2 -0
  37. package/dist/lib/interfaces/hooks.interface.d.ts +52 -0
  38. package/dist/lib/interfaces/hooks.interface.d.ts.map +1 -0
  39. package/dist/lib/interfaces/hooks.interface.js +2 -0
  40. package/dist/lib/nest-crud.module.d.ts.map +1 -1
  41. package/dist/lib/nest-crud.module.js +6 -3
  42. package/dist/lib/services/audit-log.service.d.ts +43 -0
  43. package/dist/lib/services/audit-log.service.d.ts.map +1 -0
  44. package/dist/lib/services/audit-log.service.js +154 -0
  45. package/dist/lib/services/nest-crud.service.d.ts +23 -4
  46. package/dist/lib/services/nest-crud.service.d.ts.map +1 -1
  47. package/dist/lib/services/nest-crud.service.js +165 -9
  48. package/package.json +14 -5
package/README.md CHANGED
@@ -7,11 +7,21 @@ This library was generated with [Nx](https://nx.dev).
7
7
  To install this library in your project, use the permanent URL from the latest GitHub Release:
8
8
 
9
9
  ```bash
10
- pnpm add https://github.com/nigussolomon/nest-util/releases/download/latest/nest-util-nest-crud-0.0.1.tgz
10
+ pnpm add https://github.com/nigussolomon/nest-util/releases/download/latest/nest-util-nest-crud-0.1.1.tgz
11
11
  ```
12
12
 
13
- > [!TIP]
14
- > This tarball contains only the compiled code and its specific dependencies, making it as clean as a standard npm package.
13
+ > **Tip:** This tarball contains only the compiled code and its specific dependencies, making it as clean as a standard npm package.
14
+
15
+ ## Features
16
+
17
+ - Generic CRUD service with filtering, pagination, and sorting
18
+ - Controller factory that generates 7 REST endpoints
19
+ - Built-in audit logging with `@Audit()` decorator
20
+ - Lifecycle hooks (before/after) with transaction support
21
+ - Cursor-based pagination for efficient large-dataset traversal
22
+ - User-scoped record retrieval via `GET /resource/mine`
23
+ - Automatic Swagger documentation
24
+ - TypeORM exception filter for duplicate key errors
15
25
 
16
26
  ## Building
17
27
 
package/dist/index.d.ts CHANGED
@@ -3,9 +3,19 @@ export * from './lib/services/nest-crud.service';
3
3
  export * from './lib/controllers/nest-crud.controller';
4
4
  export * from './lib/dtos/filter.dto';
5
5
  export * from './lib/dtos/pagination.dto';
6
+ export * from './lib/dtos/cursor-pagination.dto';
7
+ export * from './lib/dtos/list-audit-logs.dto';
6
8
  export * from './lib/decorators/response-message.decorator';
9
+ export * from './lib/decorators/audit-log.decorator';
7
10
  export * from './lib/interceptors/response.interceptor';
11
+ export * from './lib/interceptors/audit-log.interceptor';
8
12
  export * from './lib/interfaces/crud.interface';
13
+ export * from './lib/interfaces/cursor-strategy.interface';
14
+ export * from './lib/interfaces/hooks.interface';
15
+ export * from './lib/interfaces/find-mine.interface';
16
+ export * from './lib/interfaces/audit-log.interface';
9
17
  export * from './lib/helpers/exception-filter.helper';
10
- export { Audit, AuditLogEntity } from '@nest-util/nest-audit';
18
+ export * from './lib/helpers/cursor-pagination.helper';
19
+ export * from './lib/entities/audit-log.entity';
20
+ export * from './lib/services/audit-log.service';
11
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,yCAAyC,CAAC;AACxD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,wCAAwC,CAAC;AACvD,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,0CAA0C,CAAC;AACzD,cAAc,iCAAiC,CAAC;AAChD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,wCAAwC,CAAC;AACvD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC"}
package/dist/index.js CHANGED
@@ -1,16 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AuditLogEntity = exports.Audit = void 0;
4
3
  const tslib_1 = require("tslib");
5
4
  tslib_1.__exportStar(require("./lib/nest-crud.module"), exports);
6
5
  tslib_1.__exportStar(require("./lib/services/nest-crud.service"), exports);
7
6
  tslib_1.__exportStar(require("./lib/controllers/nest-crud.controller"), exports);
8
7
  tslib_1.__exportStar(require("./lib/dtos/filter.dto"), exports);
9
8
  tslib_1.__exportStar(require("./lib/dtos/pagination.dto"), exports);
9
+ tslib_1.__exportStar(require("./lib/dtos/cursor-pagination.dto"), exports);
10
+ tslib_1.__exportStar(require("./lib/dtos/list-audit-logs.dto"), exports);
10
11
  tslib_1.__exportStar(require("./lib/decorators/response-message.decorator"), exports);
12
+ tslib_1.__exportStar(require("./lib/decorators/audit-log.decorator"), exports);
11
13
  tslib_1.__exportStar(require("./lib/interceptors/response.interceptor"), exports);
14
+ tslib_1.__exportStar(require("./lib/interceptors/audit-log.interceptor"), exports);
12
15
  tslib_1.__exportStar(require("./lib/interfaces/crud.interface"), exports);
16
+ tslib_1.__exportStar(require("./lib/interfaces/cursor-strategy.interface"), exports);
17
+ tslib_1.__exportStar(require("./lib/interfaces/hooks.interface"), exports);
18
+ tslib_1.__exportStar(require("./lib/interfaces/find-mine.interface"), exports);
19
+ tslib_1.__exportStar(require("./lib/interfaces/audit-log.interface"), exports);
13
20
  tslib_1.__exportStar(require("./lib/helpers/exception-filter.helper"), exports);
14
- var nest_audit_1 = require("@nest-util/nest-audit");
15
- Object.defineProperty(exports, "Audit", { enumerable: true, get: function () { return nest_audit_1.Audit; } });
16
- Object.defineProperty(exports, "AuditLogEntity", { enumerable: true, get: function () { return nest_audit_1.AuditLogEntity; } });
21
+ tslib_1.__exportStar(require("./lib/helpers/cursor-pagination.helper"), exports);
22
+ tslib_1.__exportStar(require("./lib/entities/audit-log.entity"), exports);
23
+ tslib_1.__exportStar(require("./lib/services/audit-log.service"), exports);
@@ -2,12 +2,13 @@ import { Type } from '@nestjs/common';
2
2
  import { CrudEndpoint, CrudInterface } from '../interfaces/crud.interface';
3
3
  import { PaginationDto } from '../dtos/pagination.dto';
4
4
  import { FilterDto } from '../dtos/filter.dto';
5
- import { ListAuditLogsDto } from '@nest-util/nest-audit';
5
+ import { ListAuditLogsDto } from '../dtos/list-audit-logs.dto';
6
6
  export declare const AUTH_PERMISSIONS_METADATA_KEY = "auth:permissions";
7
7
  export type CrudEndpointPermissions = string | readonly string[];
8
8
  export type CrudPermissionsMap = Partial<Record<CrudEndpoint, CrudEndpointPermissions>>;
9
9
  export interface CrudControllerFactoryOptions {
10
10
  permissions?: CrudPermissionsMap;
11
+ enableFindMine?: boolean;
11
12
  }
12
13
  export interface IBaseController<CD, UD, RD> {
13
14
  service: CrudInterface<CD, UD, RD>;
@@ -1 +1 @@
1
- {"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAS,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAC9C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,CACL,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAyDD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACnD,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CA2FnC"}
1
+ {"version":3,"file":"nest-crud.controller.d.ts","sourceRoot":"","sources":["../../../src/lib/controllers/nest-crud.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAC9C,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;IACzC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,CACL,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,OAAO,CAAC;QAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAyDD,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACnD,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,EACnB,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,EACrB,OAAO,CAAC,EAAE,4BAA4B,GACrC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CA8HnC"}
@@ -6,7 +6,9 @@ const tslib_1 = require("tslib");
6
6
  const common_1 = require("@nestjs/common");
7
7
  const swagger_1 = require("@nestjs/swagger");
8
8
  const response_message_decorator_1 = require("../decorators/response-message.decorator");
9
- const nest_audit_1 = require("@nest-util/nest-audit");
9
+ const audit_log_decorator_1 = require("../decorators/audit-log.decorator");
10
+ const list_audit_logs_dto_1 = require("../dtos/list-audit-logs.dto");
11
+ const nest_auth_1 = require("@nest-util/nest-auth");
10
12
  exports.AUTH_PERMISSIONS_METADATA_KEY = 'auth:permissions';
11
13
  const toPermissionList = (permissionValue) => {
12
14
  if (Array.isArray(permissionValue)) {
@@ -50,8 +52,22 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
50
52
  }
51
53
  findAll(query) {
52
54
  this.ensureEndpointEnabled('findAll');
55
+ // Cursor-based pagination: dispatch to cursor endpoint
56
+ if (query.cursor !== undefined) {
57
+ if (!this.service.findAllWithCursor) {
58
+ throw new common_1.NotFoundException('Resource not found');
59
+ }
60
+ return this.service.findAllWithCursor(query);
61
+ }
53
62
  return this.service.findAll(query);
54
63
  }
64
+ findMine(user, query) {
65
+ this.ensureEndpointEnabled('findMine');
66
+ if (!this.service.findMine) {
67
+ throw new common_1.NotFoundException('Resource not found');
68
+ }
69
+ return this.service.findMine(user.id, query);
70
+ }
55
71
  create(dto) {
56
72
  this.ensureEndpointEnabled('create');
57
73
  return this.service.create(dto);
@@ -100,15 +116,35 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
100
116
  required: false,
101
117
  enum: ['ASC', 'DESC'],
102
118
  }),
119
+ (0, swagger_1.ApiQuery)({ name: 'cursor', required: false, type: String }),
120
+ (0, swagger_1.ApiQuery)({ name: 'includeTotal', required: false, type: Boolean }),
103
121
  tslib_1.__param(0, (0, common_1.Query)()),
104
122
  tslib_1.__metadata("design:type", Function),
105
123
  tslib_1.__metadata("design:paramtypes", [Object]),
106
124
  tslib_1.__metadata("design:returntype", void 0)
107
125
  ], BaseController.prototype, "findAll", null);
126
+ tslib_1.__decorate([
127
+ (0, common_1.Get)('mine'),
128
+ (0, response_message_decorator_1.Message)('fetched'),
129
+ (0, swagger_1.ApiResponse)({ type: [responseDto] }),
130
+ (0, swagger_1.ApiQuery)({ name: 'page', required: false, type: Number }),
131
+ (0, swagger_1.ApiQuery)({ name: 'limit', required: false, type: Number }),
132
+ (0, swagger_1.ApiQuery)({ name: 'orderBy', required: false, type: String }),
133
+ (0, swagger_1.ApiQuery)({
134
+ name: 'orderDirection',
135
+ required: false,
136
+ enum: ['ASC', 'DESC'],
137
+ }),
138
+ tslib_1.__param(0, (0, nest_auth_1.CurrentUser)()),
139
+ tslib_1.__param(1, (0, common_1.Query)()),
140
+ tslib_1.__metadata("design:type", Function),
141
+ tslib_1.__metadata("design:paramtypes", [Object, Object]),
142
+ tslib_1.__metadata("design:returntype", void 0)
143
+ ], BaseController.prototype, "findMine", null);
108
144
  tslib_1.__decorate([
109
145
  (0, common_1.Post)(),
110
146
  (0, response_message_decorator_1.Message)('created'),
111
- (0, nest_audit_1.Audit)({ action: 'CREATE' }),
147
+ (0, audit_log_decorator_1.Audit)({ action: 'CREATE' }),
112
148
  (0, swagger_1.ApiBody)({ type: createDto }),
113
149
  (0, swagger_1.ApiResponse)({ type: responseDto }),
114
150
  tslib_1.__param(0, (0, common_1.Body)()),
@@ -119,7 +155,7 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
119
155
  tslib_1.__decorate([
120
156
  (0, common_1.Patch)(':id'),
121
157
  (0, response_message_decorator_1.Message)('updated'),
122
- (0, nest_audit_1.Audit)({ action: 'UPDATE' }),
158
+ (0, audit_log_decorator_1.Audit)({ action: 'UPDATE' }),
123
159
  (0, swagger_1.ApiBody)({ type: updateDto }),
124
160
  (0, swagger_1.ApiResponse)({ type: responseDto }),
125
161
  tslib_1.__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
@@ -131,7 +167,7 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
131
167
  tslib_1.__decorate([
132
168
  (0, common_1.Delete)(':id'),
133
169
  (0, response_message_decorator_1.Message)('deleted'),
134
- (0, nest_audit_1.Audit)({ action: 'DELETE' }),
170
+ (0, audit_log_decorator_1.Audit)({ action: 'DELETE' }),
135
171
  tslib_1.__param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
136
172
  tslib_1.__metadata("design:type", Function),
137
173
  tslib_1.__metadata("design:paramtypes", [Number]),
@@ -142,7 +178,7 @@ function CreateNestedCrudController(createDto, updateDto, responseDto, options)
142
178
  (0, response_message_decorator_1.Message)('fetched'),
143
179
  tslib_1.__param(0, (0, common_1.Query)()),
144
180
  tslib_1.__metadata("design:type", Function),
145
- tslib_1.__metadata("design:paramtypes", [nest_audit_1.ListAuditLogsDto]),
181
+ tslib_1.__metadata("design:paramtypes", [list_audit_logs_dto_1.ListAuditLogsDto]),
146
182
  tslib_1.__metadata("design:returntype", void 0)
147
183
  ], BaseController.prototype, "findAuditLogs", null);
148
184
  tslib_1.__decorate([
@@ -0,0 +1,7 @@
1
+ export declare const AUDIT_METADATA_KEY = "nest_util_audit";
2
+ export interface AuditOptions {
3
+ action: string;
4
+ entity?: string;
5
+ }
6
+ export declare const Audit: (options: AuditOptions) => import("@nestjs/common").CustomDecorator<string>;
7
+ //# sourceMappingURL=audit-log.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/audit-log.decorator.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,KAAK,GAAI,SAAS,YAAY,qDACD,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Audit = exports.AUDIT_METADATA_KEY = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.AUDIT_METADATA_KEY = 'nest_util_audit';
6
+ const Audit = (options) => (0, common_1.SetMetadata)(exports.AUDIT_METADATA_KEY, options);
7
+ exports.Audit = Audit;
@@ -0,0 +1,6 @@
1
+ export declare class CursorPaginationDto {
2
+ cursor?: string;
3
+ limit?: number;
4
+ includeTotal?: boolean;
5
+ }
6
+ //# sourceMappingURL=cursor-pagination.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-pagination.dto.d.ts","sourceRoot":"","sources":["../../../src/lib/dtos/cursor-pagination.dto.ts"],"names":[],"mappings":"AAIA,qBAAa,mBAAmB;IAO9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAahB,KAAK,CAAC,EAAE,MAAM,CAAM;IASpB,YAAY,CAAC,EAAE,OAAO,CAAS;CAChC"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CursorPaginationDto = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const class_validator_1 = require("class-validator");
6
+ const class_transformer_1 = require("class-transformer");
7
+ const swagger_1 = require("@nestjs/swagger");
8
+ class CursorPaginationDto {
9
+ constructor() {
10
+ this.limit = 10;
11
+ this.includeTotal = false;
12
+ }
13
+ }
14
+ exports.CursorPaginationDto = CursorPaginationDto;
15
+ tslib_1.__decorate([
16
+ (0, swagger_1.ApiPropertyOptional)({
17
+ description: 'Opaque cursor returned from a previous response. Omit to fetch the first page.',
18
+ example: 'eyJpZCI6NDJ9',
19
+ }),
20
+ (0, class_validator_1.IsOptional)(),
21
+ (0, class_validator_1.IsString)(),
22
+ tslib_1.__metadata("design:type", String)
23
+ ], CursorPaginationDto.prototype, "cursor", void 0);
24
+ tslib_1.__decorate([
25
+ (0, swagger_1.ApiPropertyOptional)({
26
+ description: 'Maximum number of items to return',
27
+ minimum: 1,
28
+ maximum: 100,
29
+ default: 10,
30
+ }),
31
+ (0, class_validator_1.IsOptional)(),
32
+ (0, class_transformer_1.Type)(() => Number),
33
+ (0, class_validator_1.IsInt)(),
34
+ (0, class_validator_1.Min)(1),
35
+ (0, class_validator_1.Max)(100),
36
+ tslib_1.__metadata("design:type", Number)
37
+ ], CursorPaginationDto.prototype, "limit", void 0);
38
+ tslib_1.__decorate([
39
+ (0, swagger_1.ApiPropertyOptional)({
40
+ description: 'Include totalCount in the response. Disabled by default for performance.',
41
+ default: false,
42
+ }),
43
+ (0, class_validator_1.IsOptional)(),
44
+ (0, class_transformer_1.Transform)(({ value }) => value === 'true' || value === true),
45
+ (0, class_validator_1.IsBoolean)(),
46
+ tslib_1.__metadata("design:type", Boolean)
47
+ ], CursorPaginationDto.prototype, "includeTotal", void 0);
@@ -0,0 +1,8 @@
1
+ export declare class ListAuditLogsDto {
2
+ user_id?: string;
3
+ start_date?: string;
4
+ end_date?: string;
5
+ page?: number;
6
+ limit?: number;
7
+ }
8
+ //# sourceMappingURL=list-audit-logs.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-audit-logs.dto.d.ts","sourceRoot":"","sources":["../../../src/lib/dtos/list-audit-logs.dto.ts"],"names":[],"mappings":"AAIA,qBAAa,gBAAgB;IAO3B,OAAO,CAAC,EAAE,MAAM,CAAC;IAQjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAQpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAWlB,IAAI,CAAC,EAAE,MAAM,CAAK;IAWlB,KAAK,CAAC,EAAE,MAAM,CAAM;CACrB"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListAuditLogsDto = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const class_transformer_1 = require("class-transformer");
6
+ const class_validator_1 = require("class-validator");
7
+ const swagger_1 = require("@nestjs/swagger");
8
+ class ListAuditLogsDto {
9
+ constructor() {
10
+ this.page = 1;
11
+ this.limit = 10;
12
+ }
13
+ }
14
+ exports.ListAuditLogsDto = ListAuditLogsDto;
15
+ tslib_1.__decorate([
16
+ (0, swagger_1.ApiPropertyOptional)({
17
+ name: 'user_id',
18
+ description: 'Filter by user identifier',
19
+ }),
20
+ (0, class_validator_1.IsOptional)(),
21
+ (0, class_validator_1.IsString)(),
22
+ tslib_1.__metadata("design:type", String)
23
+ ], ListAuditLogsDto.prototype, "user_id", void 0);
24
+ tslib_1.__decorate([
25
+ (0, swagger_1.ApiPropertyOptional)({
26
+ name: 'start_date',
27
+ description: 'Filter logs created at or after this date (ISO-8601)',
28
+ }),
29
+ (0, class_validator_1.IsOptional)(),
30
+ (0, class_validator_1.IsDateString)(),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], ListAuditLogsDto.prototype, "start_date", void 0);
33
+ tslib_1.__decorate([
34
+ (0, swagger_1.ApiPropertyOptional)({
35
+ name: 'end_date',
36
+ description: 'Filter logs created at or before this date (ISO-8601)',
37
+ }),
38
+ (0, class_validator_1.IsOptional)(),
39
+ (0, class_validator_1.IsDateString)(),
40
+ tslib_1.__metadata("design:type", String)
41
+ ], ListAuditLogsDto.prototype, "end_date", void 0);
42
+ tslib_1.__decorate([
43
+ (0, swagger_1.ApiPropertyOptional)({
44
+ description: 'Page number',
45
+ minimum: 1,
46
+ default: 1,
47
+ }),
48
+ (0, class_validator_1.IsOptional)(),
49
+ (0, class_transformer_1.Type)(() => Number),
50
+ (0, class_validator_1.IsInt)(),
51
+ (0, class_validator_1.Min)(1),
52
+ tslib_1.__metadata("design:type", Number)
53
+ ], ListAuditLogsDto.prototype, "page", void 0);
54
+ tslib_1.__decorate([
55
+ (0, swagger_1.ApiPropertyOptional)({
56
+ description: 'Items per page',
57
+ minimum: 1,
58
+ default: 10,
59
+ }),
60
+ (0, class_validator_1.IsOptional)(),
61
+ (0, class_transformer_1.Type)(() => Number),
62
+ (0, class_validator_1.IsInt)(),
63
+ (0, class_validator_1.Min)(1),
64
+ tslib_1.__metadata("design:type", Number)
65
+ ], ListAuditLogsDto.prototype, "limit", void 0);
@@ -0,0 +1,13 @@
1
+ export declare class AuditLogEntity {
2
+ id: string;
3
+ tenantId?: string;
4
+ action: string;
5
+ entity?: string;
6
+ entityId?: string;
7
+ userId?: string;
8
+ metadata?: Record<string, unknown>;
9
+ ip?: string;
10
+ userAgent?: string;
11
+ createdAt: Date;
12
+ }
13
+ //# sourceMappingURL=audit-log.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.entity.d.ts","sourceRoot":"","sources":["../../../src/lib/entities/audit-log.entity.ts"],"names":[],"mappings":"AAQA,qBACa,cAAc;IAEzB,EAAE,EAAG,MAAM,CAAC;IAIZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,MAAM,EAAG,MAAM,CAAC;IAIhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGnC,EAAE,CAAC,EAAE,MAAM,CAAC;IAIZ,SAAS,CAAC,EAAE,MAAM,CAAC;IAInB,SAAS,EAAG,IAAI,CAAC;CAClB"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuditLogEntity = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
6
+ let AuditLogEntity = class AuditLogEntity {
7
+ };
8
+ exports.AuditLogEntity = AuditLogEntity;
9
+ tslib_1.__decorate([
10
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
11
+ tslib_1.__metadata("design:type", String)
12
+ ], AuditLogEntity.prototype, "id", void 0);
13
+ tslib_1.__decorate([
14
+ (0, typeorm_1.Index)(),
15
+ (0, typeorm_1.Column)({ nullable: true }),
16
+ tslib_1.__metadata("design:type", String)
17
+ ], AuditLogEntity.prototype, "tenantId", void 0);
18
+ tslib_1.__decorate([
19
+ (0, typeorm_1.Index)(),
20
+ (0, typeorm_1.Column)(),
21
+ tslib_1.__metadata("design:type", String)
22
+ ], AuditLogEntity.prototype, "action", void 0);
23
+ tslib_1.__decorate([
24
+ (0, typeorm_1.Index)(),
25
+ (0, typeorm_1.Column)({ nullable: true }),
26
+ tslib_1.__metadata("design:type", String)
27
+ ], AuditLogEntity.prototype, "entity", void 0);
28
+ tslib_1.__decorate([
29
+ (0, typeorm_1.Index)(),
30
+ (0, typeorm_1.Column)({ nullable: true }),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], AuditLogEntity.prototype, "entityId", void 0);
33
+ tslib_1.__decorate([
34
+ (0, typeorm_1.Index)(),
35
+ (0, typeorm_1.Column)({ nullable: true }),
36
+ tslib_1.__metadata("design:type", String)
37
+ ], AuditLogEntity.prototype, "userId", void 0);
38
+ tslib_1.__decorate([
39
+ (0, typeorm_1.Column)({ type: 'jsonb', nullable: true }),
40
+ tslib_1.__metadata("design:type", Object)
41
+ ], AuditLogEntity.prototype, "metadata", void 0);
42
+ tslib_1.__decorate([
43
+ (0, typeorm_1.Column)({ nullable: true }),
44
+ tslib_1.__metadata("design:type", String)
45
+ ], AuditLogEntity.prototype, "ip", void 0);
46
+ tslib_1.__decorate([
47
+ (0, typeorm_1.Index)(),
48
+ (0, typeorm_1.Column)({ nullable: true }),
49
+ tslib_1.__metadata("design:type", String)
50
+ ], AuditLogEntity.prototype, "userAgent", void 0);
51
+ tslib_1.__decorate([
52
+ (0, typeorm_1.Index)(),
53
+ (0, typeorm_1.CreateDateColumn)({ type: 'timestamptz' }),
54
+ tslib_1.__metadata("design:type", Date)
55
+ ], AuditLogEntity.prototype, "createdAt", void 0);
56
+ exports.AuditLogEntity = AuditLogEntity = tslib_1.__decorate([
57
+ (0, typeorm_1.Entity)('audit_logs')
58
+ ], AuditLogEntity);
@@ -0,0 +1,9 @@
1
+ import { SelectQueryBuilder, Repository } from 'typeorm';
2
+ import { CursorStrategy, DecodedCursor } from '../interfaces/cursor-strategy.interface';
3
+ export declare function base64UrlEncode(payload: Record<string, unknown>): string;
4
+ export declare function base64UrlDecode(raw: string): Record<string, unknown>;
5
+ export declare function decodeCursor(raw: string, strategy: CursorStrategy): DecodedCursor;
6
+ export declare function applyCursorFilter(qb: SelectQueryBuilder<any>, decoded: DecodedCursor, strategy: CursorStrategy, orderDirection: 'ASC' | 'DESC'): void;
7
+ export declare function buildNextCursor<T extends Record<string, unknown>>(entities: T[], strategy: CursorStrategy): string | null;
8
+ export declare function detectCursorStrategy(repository: Repository<any>): CursorStrategy;
9
+ //# sourceMappingURL=cursor-pagination.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-pagination.helper.d.ts","sourceRoot":"","sources":["../../../src/lib/helpers/cursor-pagination.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EACL,cAAc,EACd,aAAa,EAGd,MAAM,yCAAyC,CAAC;AAIjD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAMxE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGpE;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,aAAa,CAyBjF;AAKD,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAC3B,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,cAAc,EACxB,cAAc,EAAE,KAAK,GAAG,MAAM,GAC7B,IAAI,CAoBN;AAID,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,QAAQ,EAAE,CAAC,EAAE,EACb,QAAQ,EAAE,cAAc,GACvB,MAAM,GAAG,IAAI,CAcf;AAID,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,GAC1B,cAAc,CAoBhB"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.base64UrlEncode = base64UrlEncode;
4
+ exports.base64UrlDecode = base64UrlDecode;
5
+ exports.decodeCursor = decodeCursor;
6
+ exports.applyCursorFilter = applyCursorFilter;
7
+ exports.buildNextCursor = buildNextCursor;
8
+ exports.detectCursorStrategy = detectCursorStrategy;
9
+ // ─── Base64-URL helpers ──────────────────────────────────────────────
10
+ function base64UrlEncode(payload) {
11
+ return Buffer.from(JSON.stringify(payload))
12
+ .toString('base64')
13
+ .replace(/\+/g, '-')
14
+ .replace(/\//g, '_')
15
+ .replace(/=+$/, '');
16
+ }
17
+ function base64UrlDecode(raw) {
18
+ const base64 = raw.replace(/-/g, '+').replace(/_/g, '/') + '=='.slice((raw.length + 3) % 4);
19
+ return JSON.parse(Buffer.from(base64, 'base64').toString('utf8'));
20
+ }
21
+ // ─── Cursor decode / validate ─────────────────────────────────────────
22
+ function decodeCursor(raw, strategy) {
23
+ let parsed;
24
+ try {
25
+ parsed = base64UrlDecode(raw);
26
+ }
27
+ catch {
28
+ throw new Error('Invalid cursor format');
29
+ }
30
+ if (strategy.type === 'integer') {
31
+ if (typeof parsed.id !== 'number') {
32
+ throw new Error('Invalid integer cursor: missing numeric id');
33
+ }
34
+ return { type: 'integer', id: parsed.id };
35
+ }
36
+ // UUID / composite cursor
37
+ const tsCol = strategy.timestampColumn ?? 'createdAt';
38
+ if (typeof parsed[tsCol] !== 'string' || typeof parsed.id !== 'string') {
39
+ throw new Error(`Invalid UUID cursor: missing ${tsCol} or id`);
40
+ }
41
+ return {
42
+ type: 'uuid',
43
+ createdAt: parsed[tsCol],
44
+ id: parsed.id,
45
+ };
46
+ }
47
+ // ─── Query-builder mutations ──────────────────────────────────────────
48
+ /* eslint-disable @typescript-eslint/no-explicit-any */
49
+ function applyCursorFilter(qb, decoded, strategy, orderDirection) {
50
+ // DESC order means "next page" goes to lower IDs → `< :cursorId`
51
+ // ASC order means "next page" goes to higher IDs → `> :cursorId`
52
+ const comparator = orderDirection === 'DESC' ? '<' : '>';
53
+ if (decoded.type === 'integer') {
54
+ qb.andWhere(`${qb.expressionMap.mainAlias.name}.id ${comparator} :cursorId`, {
55
+ cursorId: decoded.id,
56
+ });
57
+ return;
58
+ }
59
+ // UUID composite cursor: (col1, col2) < (val1, val2)
60
+ const alias = qb.expressionMap.mainAlias.name;
61
+ const tsCol = strategy.timestampColumn ?? 'createdAt';
62
+ qb.andWhere(`(${alias}.${tsCol}, ${alias}.id) ${comparator} (:cursorTs, :cursorId)`, { cursorTs: decoded.createdAt, cursorId: decoded.id });
63
+ }
64
+ // ─── Build next cursor from result set ────────────────────────────────
65
+ function buildNextCursor(entities, strategy) {
66
+ if (entities.length === 0)
67
+ return null;
68
+ const last = entities[entities.length - 1];
69
+ if (strategy.type === 'integer') {
70
+ return base64UrlEncode({ id: Number(last['id']) });
71
+ }
72
+ const tsCol = strategy.timestampColumn ?? 'createdAt';
73
+ return base64UrlEncode({
74
+ [tsCol]: String(last[tsCol]),
75
+ id: String(last['id']),
76
+ });
77
+ }
78
+ // ─── Detect strategy from repository metadata ─────────────────────────
79
+ function detectCursorStrategy(repository) {
80
+ const primaryColumn = repository.metadata.primaryColumns[0];
81
+ if (!primaryColumn) {
82
+ return { type: 'integer' };
83
+ }
84
+ const typeValue = primaryColumn.type;
85
+ // Handle both () => String and String constructor patterns
86
+ const typeName = typeof typeValue === 'function'
87
+ ? typeValue.name
88
+ : String(typeValue);
89
+ if (typeName === 'String') {
90
+ return { type: 'uuid' };
91
+ }
92
+ return { type: 'integer' };
93
+ }
@@ -0,0 +1,12 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { Observable } from 'rxjs';
4
+ import { AuditService } from '../services/audit-log.service';
5
+ export declare class AuditInterceptor implements NestInterceptor {
6
+ private readonly auditService;
7
+ private readonly reflector;
8
+ constructor(auditService: AuditService, reflector: Reflector);
9
+ intercept(context: ExecutionContext, next: CallHandler<unknown>): Observable<unknown>;
10
+ private resolveEntityName;
11
+ }
12
+ //# sourceMappingURL=audit-log.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-log.interceptor.d.ts","sourceRoot":"","sources":["../../../src/lib/interceptors/audit-log.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAO,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAS7D,qBACa,gBAAiB,YAAW,eAAe;IAEpD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS;IAGvC,SAAS,CACP,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,GACzB,UAAU,CAAC,OAAO,CAAC;IAyCtB,OAAO,CAAC,iBAAiB;CAwB1B"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuditInterceptor = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const core_1 = require("@nestjs/core");
7
+ const rxjs_1 = require("rxjs");
8
+ const audit_log_service_1 = require("../services/audit-log.service");
9
+ const audit_log_decorator_1 = require("../decorators/audit-log.decorator");
10
+ const CONTROLLER_ENTITY_NAME_KEY = 'entityName';
11
+ const ENTITY_ENTITY_NAME_KEY = 'custom:entityName';
12
+ let AuditInterceptor = class AuditInterceptor {
13
+ constructor(auditService, reflector) {
14
+ this.auditService = auditService;
15
+ this.reflector = reflector;
16
+ }
17
+ intercept(context, next) {
18
+ const handler = context.getHandler();
19
+ const auditOptions = this.reflector.get(audit_log_decorator_1.AUDIT_METADATA_KEY, handler);
20
+ if (!auditOptions) {
21
+ return next.handle();
22
+ }
23
+ const request = context.switchToHttp().getRequest();
24
+ const userId = request.user?.id;
25
+ const ip = request.ip;
26
+ const userAgent = request.headers?.['user-agent'];
27
+ let entityName = auditOptions.entity;
28
+ if (!entityName) {
29
+ entityName = this.resolveEntityName(context);
30
+ }
31
+ return next.handle().pipe((0, rxjs_1.tap)(async (result) => {
32
+ await this.auditService.log({
33
+ action: auditOptions.action,
34
+ entity: entityName,
35
+ userId,
36
+ ip,
37
+ userAgent,
38
+ metadata: {
39
+ body: request.body,
40
+ params: request.params,
41
+ query: request.query,
42
+ response: result,
43
+ },
44
+ });
45
+ }));
46
+ }
47
+ resolveEntityName(context) {
48
+ const controllerClass = context.getClass();
49
+ const controllerMeta = Reflect.getMetadata(CONTROLLER_ENTITY_NAME_KEY, controllerClass);
50
+ if (controllerMeta?.singular) {
51
+ return controllerMeta.singular;
52
+ }
53
+ try {
54
+ const controllerInstance = controllerClass.prototype;
55
+ const serviceInstance = controllerInstance?.service;
56
+ const repositoryTarget = serviceInstance?.repository?.target;
57
+ const entityMeta = repositoryTarget
58
+ ? Reflect.getMetadata(ENTITY_ENTITY_NAME_KEY, repositoryTarget)
59
+ : null;
60
+ return entityMeta?.singular ?? 'Resource';
61
+ }
62
+ catch {
63
+ return 'Resource';
64
+ }
65
+ }
66
+ };
67
+ exports.AuditInterceptor = AuditInterceptor;
68
+ exports.AuditInterceptor = AuditInterceptor = tslib_1.__decorate([
69
+ (0, common_1.Injectable)(),
70
+ tslib_1.__metadata("design:paramtypes", [audit_log_service_1.AuditService,
71
+ core_1.Reflector])
72
+ ], AuditInterceptor);