@flusys/nestjs-shared 1.0.0-beta → 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 (113) hide show
  1. package/README.md +501 -720
  2. package/cjs/classes/api-controller.class.js +9 -24
  3. package/cjs/classes/api-service.class.js +59 -92
  4. package/cjs/classes/index.js +1 -0
  5. package/cjs/classes/winston-logger-adapter.class.js +23 -40
  6. package/cjs/constants/index.js +14 -0
  7. package/cjs/constants/permissions.js +184 -0
  8. package/cjs/decorators/api-response.decorator.js +1 -1
  9. package/cjs/decorators/index.js +1 -0
  10. package/cjs/decorators/sanitize-html.decorator.js +36 -0
  11. package/cjs/dtos/delete.dto.js +10 -0
  12. package/cjs/dtos/filter-and-pagination.dto.js +24 -34
  13. package/cjs/dtos/pagination.dto.js +4 -8
  14. package/cjs/dtos/response-payload.dto.js +0 -116
  15. package/cjs/entities/identity.js +4 -4
  16. package/cjs/entities/user-root.js +13 -14
  17. package/cjs/guards/permission.guard.js +51 -105
  18. package/cjs/interceptors/index.js +1 -3
  19. package/cjs/interceptors/set-user-field-on-body.interceptor.js +60 -0
  20. package/cjs/interceptors/slug.interceptor.js +30 -9
  21. package/cjs/interfaces/datasource.interface.js +4 -0
  22. package/cjs/interfaces/index.js +2 -1
  23. package/cjs/interfaces/module-config.interface.js +4 -0
  24. package/cjs/middlewares/logger.middleware.js +50 -89
  25. package/cjs/modules/cache/cache.module.js +3 -3
  26. package/cjs/modules/datasource/datasource.module.js +11 -14
  27. package/cjs/modules/datasource/multi-tenant-datasource.service.js +29 -113
  28. package/cjs/modules/utils/utils.service.js +40 -203
  29. package/cjs/utils/error-handler.util.js +35 -12
  30. package/cjs/utils/html-sanitizer.util.js +64 -0
  31. package/cjs/utils/index.js +4 -0
  32. package/cjs/utils/query-helpers.util.js +53 -0
  33. package/cjs/utils/request.util.js +70 -0
  34. package/cjs/utils/string.util.js +63 -0
  35. package/classes/api-controller.class.d.ts +5 -5
  36. package/classes/api-service.class.d.ts +7 -5
  37. package/classes/index.d.ts +1 -0
  38. package/classes/request-scoped-api.service.d.ts +3 -2
  39. package/classes/winston-logger-adapter.class.d.ts +2 -0
  40. package/constants/index.d.ts +1 -0
  41. package/constants/permissions.d.ts +179 -0
  42. package/decorators/index.d.ts +1 -0
  43. package/decorators/sanitize-html.decorator.d.ts +2 -0
  44. package/dtos/delete.dto.d.ts +1 -0
  45. package/dtos/filter-and-pagination.dto.d.ts +0 -2
  46. package/dtos/response-payload.dto.d.ts +0 -20
  47. package/fesm/classes/api-controller.class.js +9 -24
  48. package/fesm/classes/api-service.class.js +59 -92
  49. package/fesm/classes/index.js +2 -0
  50. package/fesm/classes/winston-logger-adapter.class.js +23 -40
  51. package/fesm/constants/index.js +2 -0
  52. package/fesm/constants/permissions.js +128 -0
  53. package/fesm/decorators/api-response.decorator.js +1 -1
  54. package/fesm/decorators/index.js +1 -0
  55. package/fesm/decorators/sanitize-html.decorator.js +45 -0
  56. package/fesm/dtos/delete.dto.js +12 -2
  57. package/fesm/dtos/filter-and-pagination.dto.js +26 -47
  58. package/fesm/dtos/pagination.dto.js +4 -8
  59. package/fesm/dtos/response-payload.dto.js +0 -107
  60. package/fesm/entities/identity.js +4 -4
  61. package/fesm/entities/user-root.js +13 -14
  62. package/fesm/guards/permission.guard.js +51 -105
  63. package/fesm/interceptors/index.js +1 -3
  64. package/fesm/interceptors/set-user-field-on-body.interceptor.js +39 -0
  65. package/fesm/interceptors/slug.interceptor.js +31 -10
  66. package/fesm/interfaces/datasource.interface.js +20 -0
  67. package/fesm/interfaces/index.js +2 -1
  68. package/fesm/interfaces/module-config.interface.js +5 -0
  69. package/fesm/middlewares/logger.middleware.js +50 -83
  70. package/fesm/modules/cache/cache.module.js +2 -2
  71. package/fesm/modules/datasource/datasource.module.js +11 -14
  72. package/fesm/modules/datasource/multi-tenant-datasource.service.js +29 -113
  73. package/fesm/modules/utils/utils.service.js +41 -204
  74. package/fesm/utils/error-handler.util.js +36 -13
  75. package/fesm/utils/html-sanitizer.util.js +69 -0
  76. package/fesm/utils/index.js +4 -0
  77. package/fesm/utils/query-helpers.util.js +78 -0
  78. package/fesm/utils/request.util.js +58 -0
  79. package/fesm/utils/string.util.js +71 -0
  80. package/guards/permission.guard.d.ts +2 -0
  81. package/interceptors/index.d.ts +1 -3
  82. package/interceptors/set-user-field-on-body.interceptor.d.ts +5 -0
  83. package/interceptors/slug.interceptor.d.ts +2 -1
  84. package/interfaces/api.interface.d.ts +2 -2
  85. package/interfaces/datasource.interface.d.ts +5 -0
  86. package/interfaces/identity.interface.d.ts +4 -4
  87. package/interfaces/index.d.ts +2 -1
  88. package/interfaces/logged-user-info.interface.d.ts +0 -2
  89. package/interfaces/module-config.interface.d.ts +6 -0
  90. package/interfaces/permission.interface.d.ts +0 -1
  91. package/middlewares/logger.middleware.d.ts +2 -2
  92. package/modules/datasource/datasource.module.d.ts +1 -0
  93. package/modules/datasource/multi-tenant-datasource.service.d.ts +0 -1
  94. package/modules/utils/utils.service.d.ts +4 -14
  95. package/package.json +4 -4
  96. package/utils/error-handler.util.d.ts +14 -19
  97. package/utils/html-sanitizer.util.d.ts +2 -0
  98. package/utils/index.d.ts +4 -0
  99. package/utils/query-helpers.util.d.ts +16 -0
  100. package/utils/request.util.d.ts +4 -0
  101. package/utils/string.util.d.ts +2 -0
  102. package/cjs/interceptors/set-create-by-on-body.interceptor.js +0 -40
  103. package/cjs/interceptors/set-delete-by-on-body.interceptor.js +0 -40
  104. package/cjs/interceptors/set-update-by-on-body.interceptor.js +0 -40
  105. package/cjs/interfaces/base-query.interface.js +0 -6
  106. package/fesm/interceptors/set-create-by-on-body.interceptor.js +0 -30
  107. package/fesm/interceptors/set-delete-by-on-body.interceptor.js +0 -30
  108. package/fesm/interceptors/set-update-by-on-body.interceptor.js +0 -30
  109. package/fesm/interfaces/base-query.interface.js +0 -3
  110. package/interceptors/set-create-by-on-body.interceptor.d.ts +0 -5
  111. package/interceptors/set-delete-by-on-body.interceptor.d.ts +0 -5
  112. package/interceptors/set-update-by-on-body.interceptor.d.ts +0 -5
  113. package/interfaces/base-query.interface.d.ts +0 -7
@@ -8,10 +8,10 @@ Object.defineProperty(exports, "createApiController", {
8
8
  return createApiController;
9
9
  }
10
10
  });
11
- const _decorators = require("@flusys/nestjs-shared/decorators");
12
- const _dtos = require("@flusys/nestjs-shared/dtos");
13
- const _guards = require("@flusys/nestjs-shared/guards");
14
- const _interceptors = require("@flusys/nestjs-shared/interceptors");
11
+ const _decorators = require("../decorators");
12
+ const _dtos = require("../dtos");
13
+ const _guards = require("../guards");
14
+ const _interceptors = require("../interceptors");
15
15
  const _common = require("@nestjs/common");
16
16
  const _swagger = require("@nestjs/swagger");
17
17
  const _classtransformer = require("class-transformer");
@@ -104,8 +104,10 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
104
104
  // 2. It's an object with 'level' property but no endpoint keys
105
105
  const isGlobalSecurity = typeof securityConfig === 'string' || securityConfig && typeof securityConfig === 'object' && 'level' in securityConfig && !endpointKeys.some((key)=>key in securityConfig);
106
106
  // Normalize security config for each endpoint
107
+ // IMPORTANT: When per-endpoint security is specified, default to 'jwt' for unconfigured endpoints
108
+ // to prevent accidentally exposing endpoints without authentication
107
109
  const defaultSecurity = isGlobalSecurity ? normalizeSecurity(securityConfig) : {
108
- level: 'public'
110
+ level: 'jwt'
109
111
  };
110
112
  const security = {
111
113
  insert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insert),
@@ -347,16 +349,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
347
349
  (0, _common.HttpCode)(_common.HttpStatus.OK),
348
350
  (0, _swagger.ApiOperation)({
349
351
  summary: 'Get all items with filters and pagination',
350
- description: `
351
- Retrieves items with support for:
352
- - **filter**: Apply field-based filters (e.g., \`{ "isActive": true }\`)
353
- - **pagination**: Control page and page size
354
- - **sort**: Order by any field (e.g., \`{ "createdAt": "DESC" }\`)
355
- - **select**: Choose specific fields to return
356
- - **withDeleted**: Include soft-deleted items
357
- - **extraKey**: Include additional relations
358
- - **q** (query param): Global text search
359
- `
352
+ description: 'Supports filter, pagination, sort, select, withDeleted, and q (search) params'
360
353
  }),
361
354
  (0, _swagger.ApiQuery)({
362
355
  name: 'q',
@@ -385,15 +378,7 @@ Retrieves items with support for:
385
378
  (0, _common.HttpCode)(_common.HttpStatus.OK),
386
379
  (0, _swagger.ApiOperation)({
387
380
  summary: 'Delete, restore, or permanently remove items',
388
- description: `
389
- Performs one of three actions:
390
-
391
- - **"delete"** (soft delete): Marks items as deleted but keeps in database
392
- - **"restore"**: Reverts soft-deleted items to active
393
- - **"permanent"**: Completely removes items from database
394
-
395
- Supports single ID or array of IDs for batch operations.
396
- `
381
+ description: 'Types: delete (soft), restore, permanent. Supports batch IDs.'
397
382
  }),
398
383
  (0, _swagger.ApiResponse)({
399
384
  status: 200,
@@ -26,116 +26,52 @@ function _define_property(obj, key, value) {
26
26
  }
27
27
  let ApiService = class ApiService {
28
28
  async insert(dto, user) {
29
- await this.ensureRepositoryInitialized();
30
- const qr = this.repository.manager.connection.createQueryRunner();
31
- await qr.connect();
32
- await qr.startTransaction();
33
- try {
29
+ return this.executeInTransaction('insert', async (qr)=>{
34
30
  await this.beforeInsertOperation(dto, user, qr);
35
31
  const entities = await this.convertRequestDtoToEntity(dto, user);
36
32
  const saved = await qr.manager.save(this.repository.target, entities);
37
- await this.afterInsertOperation(saved, user, qr);
38
- await qr.commitTransaction();
39
- if (this.isCacheable) await Promise.all([
40
- this.clearCacheForAll(),
41
- this.clearCacheForId(Array.isArray(saved) ? saved : [
42
- saved
43
- ])
44
- ]);
45
- const first = Array.isArray(saved) ? saved[0] : saved;
46
- return this.convertEntityToResponseDto(first, false);
47
- } catch (error) {
48
- await qr.rollbackTransaction();
49
- this.handleError(error, 'insert');
50
- } finally{
51
- await qr.release();
52
- }
33
+ await this.afterInsertOperation(this.ensureArray(saved), user, qr);
34
+ return {
35
+ saved,
36
+ returnFirst: true
37
+ };
38
+ });
53
39
  }
54
40
  async insertMany(dtos, user) {
55
- await this.ensureRepositoryInitialized();
56
- const qr = this.repository.manager.connection.createQueryRunner();
57
- await qr.connect();
58
- await qr.startTransaction();
59
- try {
41
+ return this.executeInTransaction('insertMany', async (qr)=>{
60
42
  await this.beforeInsertOperation(dtos, user, qr);
61
43
  const entities = await this.convertRequestDtoToEntity(dtos, user);
62
44
  const saved = await qr.manager.save(this.repository.target, entities);
63
- await this.afterInsertOperation(Array.isArray(saved) ? saved : [
64
- saved
65
- ], user, qr);
66
- await qr.commitTransaction();
67
- if (this.isCacheable) await Promise.all([
68
- this.clearCacheForAll(),
69
- this.clearCacheForId(Array.isArray(saved) ? saved : [
70
- saved
71
- ])
72
- ]);
73
- const list = (Array.isArray(saved) ? saved : [
74
- saved
75
- ]).map((e)=>this.convertEntityToResponseDto(e, false));
76
- return list;
77
- } catch (error) {
78
- await qr.rollbackTransaction();
79
- this.handleError(error, 'insertMany');
80
- } finally{
81
- await qr.release();
82
- }
45
+ await this.afterInsertOperation(this.ensureArray(saved), user, qr);
46
+ return {
47
+ saved,
48
+ returnFirst: false
49
+ };
50
+ });
83
51
  }
84
52
  async update(dto, user) {
85
- await this.ensureRepositoryInitialized();
86
- const qr = this.repository.manager.connection.createQueryRunner();
87
- await qr.connect();
88
- await qr.startTransaction();
89
- try {
53
+ return this.executeInTransaction('update', async (qr)=>{
90
54
  await this.beforeUpdateOperation(dto, user, qr);
91
55
  const entities = await this.convertRequestDtoToEntity(dto, user);
92
56
  const saved = await qr.manager.save(this.repository.target, entities);
93
- await this.afterUpdateOperation(saved, user, qr);
94
- await qr.commitTransaction();
95
- if (this.isCacheable) await Promise.all([
96
- this.clearCacheForAll(),
97
- this.clearCacheForId(Array.isArray(saved) ? saved : [
98
- saved
99
- ])
100
- ]);
101
- const first = Array.isArray(saved) ? saved[0] : saved;
102
- return this.convertEntityToResponseDto(first, false);
103
- } catch (error) {
104
- await qr.rollbackTransaction();
105
- this.handleError(error, 'update');
106
- } finally{
107
- await qr.release();
108
- }
57
+ await this.afterUpdateOperation(this.ensureArray(saved), user, qr);
58
+ return {
59
+ saved,
60
+ returnFirst: true
61
+ };
62
+ });
109
63
  }
110
64
  async updateMany(dtos, user) {
111
- await this.ensureRepositoryInitialized();
112
- const qr = this.repository.manager.connection.createQueryRunner();
113
- await qr.connect();
114
- await qr.startTransaction();
115
- try {
65
+ return this.executeInTransaction('updateMany', async (qr)=>{
116
66
  await this.beforeUpdateOperation(dtos, user, qr);
117
67
  const entities = await this.convertRequestDtoToEntity(dtos, user);
118
68
  const saved = await qr.manager.save(this.repository.target, entities);
119
- await this.afterUpdateOperation(Array.isArray(saved) ? saved : [
120
- saved
121
- ], user, qr);
122
- await qr.commitTransaction();
123
- if (this.isCacheable) await Promise.all([
124
- this.clearCacheForAll(),
125
- this.clearCacheForId(Array.isArray(saved) ? saved : [
126
- saved
127
- ])
128
- ]);
129
- const list = (Array.isArray(saved) ? saved : [
130
- saved
131
- ]).map((e)=>this.convertEntityToResponseDto(e, false));
132
- return list;
133
- } catch (error) {
134
- await qr.rollbackTransaction();
135
- this.handleError(error, 'updateMany');
136
- } finally{
137
- await qr.release();
138
- }
69
+ await this.afterUpdateOperation(this.ensureArray(saved), user, qr);
70
+ return {
71
+ saved,
72
+ returnFirst: false
73
+ };
74
+ });
139
75
  }
140
76
  async findByIds(ids, user) {
141
77
  await this.ensureRepositoryInitialized();
@@ -354,6 +290,37 @@ let ApiService = class ApiService {
354
290
  });
355
291
  _errorhandlerutil.ErrorHandler.rethrowError(error);
356
292
  }
293
+ /** Ensures value is always an array */ ensureArray(value) {
294
+ return Array.isArray(value) ? value : [
295
+ value
296
+ ];
297
+ }
298
+ /** Executes operation in transaction with automatic cache clearing */ async executeInTransaction(operation, fn) {
299
+ await this.ensureRepositoryInitialized();
300
+ const qr = this.repository.manager.connection.createQueryRunner();
301
+ await qr.connect();
302
+ await qr.startTransaction();
303
+ try {
304
+ const { saved, returnFirst } = await fn(qr);
305
+ await qr.commitTransaction();
306
+ const savedArray = this.ensureArray(saved);
307
+ if (this.isCacheable) {
308
+ await Promise.all([
309
+ this.clearCacheForAll(),
310
+ this.clearCacheForId(savedArray)
311
+ ]);
312
+ }
313
+ if (returnFirst) {
314
+ return this.convertEntityToResponseDto(savedArray[0], false);
315
+ }
316
+ return savedArray.map((e)=>this.convertEntityToResponseDto(e, false));
317
+ } catch (error) {
318
+ await qr.rollbackTransaction();
319
+ this.handleError(error, operation);
320
+ } finally{
321
+ await qr.release();
322
+ }
323
+ }
357
324
  // Hooks (override in child classes)
358
325
  async ensureRepositoryInitialized() {}
359
326
  async beforeInsertOperation(_dto, _user, _queryRunner) {}
@@ -8,6 +8,7 @@ _export_star(require("./request-scoped-api.service"), exports);
8
8
  _export_star(require("./hybrid-cache.class"), exports);
9
9
  _export_star(require("./winston-logger-adapter.class"), exports);
10
10
  _export_star(require("./winston.logger.class"), exports);
11
+ _export_star(require("../constants/permissions"), exports);
11
12
  function _export_star(from, to) {
12
13
  Object.keys(from).forEach(function(k) {
13
14
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -47,46 +47,31 @@ function _define_property(obj, key, value) {
47
47
  return meta;
48
48
  }
49
49
  let WinstonLoggerAdapter = class WinstonLoggerAdapter {
50
- log(message, context, ...args) {
51
- const meta = args.length > 0 && typeof args[0] === 'object' ? args[0] : {};
52
- _winstonloggerclass.instance.info(message, {
50
+ buildLogMeta(context, args, extra) {
51
+ const meta = args?.length && typeof args[0] === 'object' ? args[0] : {};
52
+ return {
53
53
  context: context || this.context,
54
54
  ...getCorrelationMeta(),
55
- ...meta
56
- });
55
+ ...meta,
56
+ ...extra
57
+ };
58
+ }
59
+ log(message, context, ...args) {
60
+ _winstonloggerclass.instance.info(message, this.buildLogMeta(context, args));
57
61
  }
58
62
  error(message, trace, context, ...args) {
59
- const meta = args.length > 0 && typeof args[0] === 'object' ? args[0] : {};
60
- _winstonloggerclass.instance.error(message, {
61
- context: context || this.context,
62
- stack: trace,
63
- ...getCorrelationMeta(),
64
- ...meta
65
- });
63
+ _winstonloggerclass.instance.error(message, this.buildLogMeta(context, args, {
64
+ stack: trace
65
+ }));
66
66
  }
67
67
  warn(message, context, ...args) {
68
- const meta = args.length > 0 && typeof args[0] === 'object' ? args[0] : {};
69
- _winstonloggerclass.instance.warn(message, {
70
- context: context || this.context,
71
- ...getCorrelationMeta(),
72
- ...meta
73
- });
68
+ _winstonloggerclass.instance.warn(message, this.buildLogMeta(context, args));
74
69
  }
75
70
  debug(message, context, ...args) {
76
- const meta = args.length > 0 && typeof args[0] === 'object' ? args[0] : {};
77
- _winstonloggerclass.instance.debug(message, {
78
- context: context || this.context,
79
- ...getCorrelationMeta(),
80
- ...meta
81
- });
71
+ _winstonloggerclass.instance.debug(message, this.buildLogMeta(context, args));
82
72
  }
83
73
  verbose(message, context, ...args) {
84
- const meta = args.length > 0 && typeof args[0] === 'object' ? args[0] : {};
85
- _winstonloggerclass.instance.verbose(message, {
86
- context: context || this.context,
87
- ...getCorrelationMeta(),
88
- ...meta
89
- });
74
+ _winstonloggerclass.instance.verbose(message, this.buildLogMeta(context, args));
90
75
  }
91
76
  constructor(context){
92
77
  _define_property(this, "context", void 0);
@@ -94,25 +79,23 @@ let WinstonLoggerAdapter = class WinstonLoggerAdapter {
94
79
  }
95
80
  };
96
81
  let NestLoggerAdapter = class NestLoggerAdapter {
82
+ formatMessage(message, args) {
83
+ return args?.length ? `${message} ${JSON.stringify(args)}` : message;
84
+ }
97
85
  log(message, context, ...args) {
98
- const logMessage = args.length > 0 ? `${message} ${JSON.stringify(args)}` : message;
99
- this.logger.log(logMessage, context);
86
+ this.logger.log(this.formatMessage(message, args), context);
100
87
  }
101
88
  error(message, trace, context, ...args) {
102
- const logMessage = args.length > 0 ? `${message} ${JSON.stringify(args)}` : message;
103
- this.logger.error(logMessage, trace, context);
89
+ this.logger.error(this.formatMessage(message, args), trace, context);
104
90
  }
105
91
  warn(message, context, ...args) {
106
- const logMessage = args.length > 0 ? `${message} ${JSON.stringify(args)}` : message;
107
- this.logger.warn(logMessage, context);
92
+ this.logger.warn(this.formatMessage(message, args), context);
108
93
  }
109
94
  debug(message, context, ...args) {
110
- const logMessage = args.length > 0 ? `${message} ${JSON.stringify(args)}` : message;
111
- this.logger.debug(logMessage, context);
95
+ this.logger.debug(this.formatMessage(message, args), context);
112
96
  }
113
97
  verbose(message, context, ...args) {
114
- const logMessage = args.length > 0 ? `${message} ${JSON.stringify(args)}` : message;
115
- this.logger.verbose(logMessage, context);
98
+ this.logger.verbose(this.formatMessage(message, args), context);
116
99
  }
117
100
  constructor(logger){
118
101
  _define_property(this, "logger", void 0);
@@ -41,6 +41,20 @@ _export(exports, {
41
41
  return REQUEST_ID_HEADER;
42
42
  }
43
43
  });
44
+ _export_star(require("./permissions"), exports);
45
+ function _export_star(from, to) {
46
+ Object.keys(from).forEach(function(k) {
47
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
48
+ Object.defineProperty(to, k, {
49
+ enumerable: true,
50
+ get: function() {
51
+ return from[k];
52
+ }
53
+ });
54
+ }
55
+ });
56
+ return from;
57
+ }
44
58
  const IS_PUBLIC_KEY = 'isPublic';
45
59
  const PERMISSIONS_KEY = 'permissions';
46
60
  const CACHE_INSTANCE = 'CACHE_INSTANCE';
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Centralized Permission Codes
3
+ *
4
+ * Single source of truth for all permission codes used across the application.
5
+ * Use these constants instead of hardcoded strings to prevent typos and enable easy refactoring.
6
+ *
7
+ * Naming Convention: <entity>.<action>
8
+ * - entity: The resource being accessed (e.g., user, role, company)
9
+ * - action: The operation being performed (create, read, update, delete, assign)
10
+ */ // ==================== AUTH MODULE ====================
11
+ "use strict";
12
+ Object.defineProperty(exports, "__esModule", {
13
+ value: true
14
+ });
15
+ function _export(target, all) {
16
+ for(var name in all)Object.defineProperty(target, name, {
17
+ enumerable: true,
18
+ get: Object.getOwnPropertyDescriptor(all, name).get
19
+ });
20
+ }
21
+ _export(exports, {
22
+ get ACTION_PERMISSIONS () {
23
+ return ACTION_PERMISSIONS;
24
+ },
25
+ get BRANCH_PERMISSIONS () {
26
+ return BRANCH_PERMISSIONS;
27
+ },
28
+ get COMPANY_ACTION_PERMISSIONS () {
29
+ return COMPANY_ACTION_PERMISSIONS;
30
+ },
31
+ get COMPANY_PERMISSIONS () {
32
+ return COMPANY_PERMISSIONS;
33
+ },
34
+ get EMAIL_CONFIG_PERMISSIONS () {
35
+ return EMAIL_CONFIG_PERMISSIONS;
36
+ },
37
+ get EMAIL_TEMPLATE_PERMISSIONS () {
38
+ return EMAIL_TEMPLATE_PERMISSIONS;
39
+ },
40
+ get FILE_PERMISSIONS () {
41
+ return FILE_PERMISSIONS;
42
+ },
43
+ get FOLDER_PERMISSIONS () {
44
+ return FOLDER_PERMISSIONS;
45
+ },
46
+ get FORM_PERMISSIONS () {
47
+ return FORM_PERMISSIONS;
48
+ },
49
+ get FORM_RESULT_PERMISSIONS () {
50
+ return FORM_RESULT_PERMISSIONS;
51
+ },
52
+ get PERMISSIONS () {
53
+ return PERMISSIONS;
54
+ },
55
+ get ROLE_ACTION_PERMISSIONS () {
56
+ return ROLE_ACTION_PERMISSIONS;
57
+ },
58
+ get ROLE_PERMISSIONS () {
59
+ return ROLE_PERMISSIONS;
60
+ },
61
+ get STORAGE_CONFIG_PERMISSIONS () {
62
+ return STORAGE_CONFIG_PERMISSIONS;
63
+ },
64
+ get USER_ACTION_PERMISSIONS () {
65
+ return USER_ACTION_PERMISSIONS;
66
+ },
67
+ get USER_PERMISSIONS () {
68
+ return USER_PERMISSIONS;
69
+ },
70
+ get USER_ROLE_PERMISSIONS () {
71
+ return USER_ROLE_PERMISSIONS;
72
+ }
73
+ });
74
+ const USER_PERMISSIONS = {
75
+ CREATE: 'user.create',
76
+ READ: 'user.read',
77
+ UPDATE: 'user.update',
78
+ DELETE: 'user.delete'
79
+ };
80
+ const COMPANY_PERMISSIONS = {
81
+ CREATE: 'company.create',
82
+ READ: 'company.read',
83
+ UPDATE: 'company.update',
84
+ DELETE: 'company.delete'
85
+ };
86
+ const BRANCH_PERMISSIONS = {
87
+ CREATE: 'branch.create',
88
+ READ: 'branch.read',
89
+ UPDATE: 'branch.update',
90
+ DELETE: 'branch.delete'
91
+ };
92
+ const ACTION_PERMISSIONS = {
93
+ CREATE: 'action.create',
94
+ READ: 'action.read',
95
+ UPDATE: 'action.update',
96
+ DELETE: 'action.delete'
97
+ };
98
+ const ROLE_PERMISSIONS = {
99
+ CREATE: 'role.create',
100
+ READ: 'role.read',
101
+ UPDATE: 'role.update',
102
+ DELETE: 'role.delete'
103
+ };
104
+ const ROLE_ACTION_PERMISSIONS = {
105
+ READ: 'role-action.read',
106
+ ASSIGN: 'role-action.assign'
107
+ };
108
+ const USER_ROLE_PERMISSIONS = {
109
+ READ: 'user-role.read',
110
+ ASSIGN: 'user-role.assign'
111
+ };
112
+ const USER_ACTION_PERMISSIONS = {
113
+ READ: 'user-action.read',
114
+ ASSIGN: 'user-action.assign'
115
+ };
116
+ const COMPANY_ACTION_PERMISSIONS = {
117
+ READ: 'company-action.read',
118
+ ASSIGN: 'company-action.assign'
119
+ };
120
+ const FILE_PERMISSIONS = {
121
+ CREATE: 'file.create',
122
+ READ: 'file.read',
123
+ UPDATE: 'file.update',
124
+ DELETE: 'file.delete'
125
+ };
126
+ const FOLDER_PERMISSIONS = {
127
+ CREATE: 'folder.create',
128
+ READ: 'folder.read',
129
+ UPDATE: 'folder.update',
130
+ DELETE: 'folder.delete'
131
+ };
132
+ const STORAGE_CONFIG_PERMISSIONS = {
133
+ CREATE: 'storage-config.create',
134
+ READ: 'storage-config.read',
135
+ UPDATE: 'storage-config.update',
136
+ DELETE: 'storage-config.delete'
137
+ };
138
+ const EMAIL_CONFIG_PERMISSIONS = {
139
+ CREATE: 'email-config.create',
140
+ READ: 'email-config.read',
141
+ UPDATE: 'email-config.update',
142
+ DELETE: 'email-config.delete'
143
+ };
144
+ const EMAIL_TEMPLATE_PERMISSIONS = {
145
+ CREATE: 'email-template.create',
146
+ READ: 'email-template.read',
147
+ UPDATE: 'email-template.update',
148
+ DELETE: 'email-template.delete'
149
+ };
150
+ const FORM_PERMISSIONS = {
151
+ CREATE: 'form.create',
152
+ READ: 'form.read',
153
+ UPDATE: 'form.update',
154
+ DELETE: 'form.delete'
155
+ };
156
+ const FORM_RESULT_PERMISSIONS = {
157
+ CREATE: 'form-result.create',
158
+ READ: 'form-result.read',
159
+ UPDATE: 'form-result.update',
160
+ DELETE: 'form-result.delete'
161
+ };
162
+ const PERMISSIONS = {
163
+ // Auth
164
+ USER: USER_PERMISSIONS,
165
+ COMPANY: COMPANY_PERMISSIONS,
166
+ BRANCH: BRANCH_PERMISSIONS,
167
+ // IAM
168
+ ACTION: ACTION_PERMISSIONS,
169
+ ROLE: ROLE_PERMISSIONS,
170
+ ROLE_ACTION: ROLE_ACTION_PERMISSIONS,
171
+ USER_ROLE: USER_ROLE_PERMISSIONS,
172
+ USER_ACTION: USER_ACTION_PERMISSIONS,
173
+ COMPANY_ACTION: COMPANY_ACTION_PERMISSIONS,
174
+ // Storage
175
+ FILE: FILE_PERMISSIONS,
176
+ FOLDER: FOLDER_PERMISSIONS,
177
+ STORAGE_CONFIG: STORAGE_CONFIG_PERMISSIONS,
178
+ // Email
179
+ EMAIL_CONFIG: EMAIL_CONFIG_PERMISSIONS,
180
+ EMAIL_TEMPLATE: EMAIL_TEMPLATE_PERMISSIONS,
181
+ // Form Builder
182
+ FORM: FORM_PERMISSIONS,
183
+ FORM_RESULT: FORM_RESULT_PERMISSIONS
184
+ };
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "ApiResponseDto", {
8
8
  return ApiResponseDto;
9
9
  }
10
10
  });
11
- const _dtos = require("@flusys/nestjs-shared/dtos");
11
+ const _dtos = require("../dtos");
12
12
  const _common = require("@nestjs/common");
13
13
  const _swagger = require("@nestjs/swagger");
14
14
  const ApiResponseDto = (dto, isArray = false, arrayType = 'list')=>{
@@ -6,6 +6,7 @@ _export_star(require("./api-response.decorator"), exports);
6
6
  _export_star(require("./current-user.decorator"), exports);
7
7
  _export_star(require("./public.decorator"), exports);
8
8
  _export_star(require("./require-permission.decorator"), exports);
9
+ _export_star(require("./sanitize-html.decorator"), exports);
9
10
  function _export_star(from, to) {
10
11
  Object.keys(from).forEach(function(k) {
11
12
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get SanitizeAndTrim () {
13
+ return SanitizeAndTrim;
14
+ },
15
+ get SanitizeHtml () {
16
+ return SanitizeHtml;
17
+ }
18
+ });
19
+ const _classtransformer = require("class-transformer");
20
+ const _htmlsanitizerutil = require("../utils/html-sanitizer.util");
21
+ function SanitizeHtml() {
22
+ return (0, _classtransformer.Transform)(({ value })=>{
23
+ if (typeof value === 'string') {
24
+ return (0, _htmlsanitizerutil.escapeHtml)(value);
25
+ }
26
+ return value;
27
+ });
28
+ }
29
+ function SanitizeAndTrim() {
30
+ return (0, _classtransformer.Transform)(({ value })=>{
31
+ if (typeof value === 'string') {
32
+ return (0, _htmlsanitizerutil.escapeHtml)(value.trim());
33
+ }
34
+ return value;
35
+ });
36
+ }
@@ -36,6 +36,7 @@ let DeleteDto = class DeleteDto {
36
36
  constructor(){
37
37
  _define_property(this, "id", void 0);
38
38
  _define_property(this, "type", void 0);
39
+ _define_property(this, "deletedById", void 0);
39
40
  }
40
41
  };
41
42
  _ts_decorate([
@@ -80,3 +81,12 @@ _ts_decorate([
80
81
  ]),
81
82
  _ts_metadata("design:type", String)
82
83
  ], DeleteDto.prototype, "type", void 0);
84
+ _ts_decorate([
85
+ (0, _swagger.ApiPropertyOptional)({
86
+ description: 'User ID who initiated the deletion (auto-set by interceptor)',
87
+ example: 'f2e9c8d0-7a2a-11eb-9439-0242ac130002'
88
+ }),
89
+ (0, _classvalidator.IsOptional)(),
90
+ (0, _classvalidator.IsUUID)(),
91
+ _ts_metadata("design:type", String)
92
+ ], DeleteDto.prototype, "deletedById", void 0);