@flusys/nestjs-shared 4.1.1 → 5.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 (60) hide show
  1. package/README.md +96 -606
  2. package/cjs/classes/api-controller.class.js +81 -10
  3. package/cjs/classes/api-service.class.js +8 -6
  4. package/cjs/classes/index.js +0 -1
  5. package/cjs/constants/index.js +0 -4
  6. package/cjs/constants/message-keys.js +3 -21
  7. package/cjs/constants/permissions.js +0 -10
  8. package/cjs/decorators/api-response.decorator.js +1 -2
  9. package/cjs/decorators/index.js +0 -1
  10. package/cjs/decorators/require-permission.decorator.js +0 -4
  11. package/cjs/exceptions/base-app.exception.js +4 -4
  12. package/cjs/exceptions/permission.exception.js +1 -1
  13. package/cjs/filters/global-exception.filter.js +4 -4
  14. package/cjs/interfaces/index.js +0 -1
  15. package/cjs/modules/datasource/multi-tenant-datasource.service.js +2 -2
  16. package/cjs/utils/date-time.util.js +94 -0
  17. package/cjs/utils/index.js +1 -0
  18. package/cjs/utils/query-helpers.util.js +2 -2
  19. package/cjs/utils/request.util.js +25 -0
  20. package/classes/index.d.ts +0 -1
  21. package/constants/index.d.ts +0 -1
  22. package/constants/message-keys.d.ts +2 -44
  23. package/constants/permissions.d.ts +0 -12
  24. package/decorators/api-response.decorator.d.ts +1 -1
  25. package/decorators/index.d.ts +0 -1
  26. package/decorators/require-permission.decorator.d.ts +0 -1
  27. package/exceptions/base-app.exception.d.ts +2 -2
  28. package/fesm/classes/api-controller.class.js +82 -11
  29. package/fesm/classes/api-service.class.js +9 -7
  30. package/fesm/classes/index.js +0 -1
  31. package/fesm/constants/index.js +0 -1
  32. package/fesm/constants/message-keys.js +3 -19
  33. package/fesm/constants/permissions.js +0 -7
  34. package/fesm/decorators/api-response.decorator.js +2 -20
  35. package/fesm/decorators/index.js +0 -1
  36. package/fesm/decorators/require-permission.decorator.js +0 -1
  37. package/fesm/exceptions/base-app.exception.js +4 -4
  38. package/fesm/exceptions/permission.exception.js +1 -1
  39. package/fesm/filters/global-exception.filter.js +4 -4
  40. package/fesm/interfaces/index.js +0 -1
  41. package/fesm/modules/datasource/multi-tenant-datasource.service.js +2 -2
  42. package/fesm/utils/date-time.util.js +70 -0
  43. package/fesm/utils/index.js +1 -0
  44. package/fesm/utils/query-helpers.util.js +2 -2
  45. package/fesm/utils/request.util.js +22 -0
  46. package/interfaces/event-manager-adapter.interface.d.ts +12 -12
  47. package/interfaces/index.d.ts +0 -1
  48. package/package.json +2 -2
  49. package/utils/date-time.util.d.ts +8 -0
  50. package/utils/index.d.ts +1 -0
  51. package/utils/request.util.d.ts +2 -0
  52. package/cjs/classes/winston-logger-adapter.class.js +0 -99
  53. package/cjs/decorators/sanitize-html.decorator.js +0 -36
  54. package/cjs/interfaces/logger.interface.js +0 -4
  55. package/classes/winston-logger-adapter.class.d.ts +0 -23
  56. package/decorators/sanitize-html.decorator.d.ts +0 -2
  57. package/fesm/classes/winston-logger-adapter.class.js +0 -81
  58. package/fesm/decorators/sanitize-html.decorator.js +0 -45
  59. package/fesm/interfaces/logger.interface.js +0 -1
  60. package/interfaces/logger.interface.d.ts +0 -7
@@ -15,6 +15,7 @@ const _decorators = require("../decorators");
15
15
  const _apiresponsedecorator = require("../decorators/api-response.decorator");
16
16
  const _dtos = require("../dtos");
17
17
  const _exceptions = require("../exceptions");
18
+ const _messagekeys = require("../constants/message-keys");
18
19
  const _guards = require("../guards");
19
20
  const _interceptors = require("../interceptors");
20
21
  function _define_property(obj, key, value) {
@@ -152,7 +153,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
152
153
  }
153
154
  async insert(addDto, user) {
154
155
  if (!this.isEnabled('insert')) {
155
- throw new _exceptions.ForbiddenException(`Endpoint 'insert' is disabled`);
156
+ throw new _exceptions.BaseAppException({
157
+ message: `Endpoint 'insert' is disabled`,
158
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
159
+ messageVariables: {
160
+ endpoint: 'insert'
161
+ },
162
+ status: _common.HttpStatus.FORBIDDEN
163
+ });
156
164
  }
157
165
  const entity = await this.service.insert(addDto, user);
158
166
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
@@ -165,7 +173,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
165
173
  }
166
174
  async insertMany(addDto, user) {
167
175
  if (!this.isEnabled('insertMany')) {
168
- throw new _exceptions.ForbiddenException(`Endpoint 'insertMany' is disabled`);
176
+ throw new _exceptions.BaseAppException({
177
+ message: `Endpoint 'insertMany' is disabled`,
178
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
179
+ messageVariables: {
180
+ endpoint: 'insertMany'
181
+ },
182
+ status: _common.HttpStatus.FORBIDDEN
183
+ });
169
184
  }
170
185
  const entities = await this.service.insertMany(addDto, user);
171
186
  const data = entities.map((item)=>(0, _classtransformer.plainToInstance)(responseDtoClass, item));
@@ -186,7 +201,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
186
201
  }
187
202
  async getById(id, body, user) {
188
203
  if (!this.isEnabled('getById')) {
189
- throw new _exceptions.ForbiddenException(`Endpoint 'getById' is disabled`);
204
+ throw new _exceptions.BaseAppException({
205
+ message: `Endpoint 'getById' is disabled`,
206
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
207
+ messageVariables: {
208
+ endpoint: 'getById'
209
+ },
210
+ status: _common.HttpStatus.FORBIDDEN
211
+ });
190
212
  }
191
213
  const entity = await this.service.findById(id, user, body?.select);
192
214
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
@@ -199,7 +221,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
199
221
  }
200
222
  async getByIds(body, user) {
201
223
  if (!this.isEnabled('getByIds')) {
202
- throw new _exceptions.ForbiddenException(`Endpoint 'getByIds' is disabled`);
224
+ throw new _exceptions.BaseAppException({
225
+ message: `Endpoint 'getByIds' is disabled`,
226
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
227
+ messageVariables: {
228
+ endpoint: 'getByIds'
229
+ },
230
+ status: _common.HttpStatus.FORBIDDEN
231
+ });
203
232
  }
204
233
  const entities = await this.service.findByIds(body.ids, user, body?.select);
205
234
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entities);
@@ -219,7 +248,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
219
248
  }
220
249
  async update(updateDto, user) {
221
250
  if (!this.isEnabled('update')) {
222
- throw new _exceptions.ForbiddenException(`Endpoint 'update' is disabled`);
251
+ throw new _exceptions.BaseAppException({
252
+ message: `Endpoint 'update' is disabled`,
253
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
254
+ messageVariables: {
255
+ endpoint: 'update'
256
+ },
257
+ status: _common.HttpStatus.FORBIDDEN
258
+ });
223
259
  }
224
260
  const entity = await this.service.update(updateDto, user);
225
261
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
@@ -232,7 +268,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
232
268
  }
233
269
  async updateMany(updateDtos, user) {
234
270
  if (!this.isEnabled('updateMany')) {
235
- throw new _exceptions.ForbiddenException(`Endpoint 'updateMany' is disabled`);
271
+ throw new _exceptions.BaseAppException({
272
+ message: `Endpoint 'updateMany' is disabled`,
273
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
274
+ messageVariables: {
275
+ endpoint: 'updateMany'
276
+ },
277
+ status: _common.HttpStatus.FORBIDDEN
278
+ });
236
279
  }
237
280
  const entities = await this.service.updateMany(updateDtos, user);
238
281
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entities);
@@ -253,7 +296,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
253
296
  }
254
297
  async bulkUpsert(dtos, user) {
255
298
  if (!this.isEnabled('bulkUpsert')) {
256
- throw new _exceptions.ForbiddenException(`Endpoint 'bulkUpsert' is disabled`);
299
+ throw new _exceptions.BaseAppException({
300
+ message: `Endpoint 'bulkUpsert' is disabled`,
301
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
302
+ messageVariables: {
303
+ endpoint: 'bulkUpsert'
304
+ },
305
+ status: _common.HttpStatus.FORBIDDEN
306
+ });
257
307
  }
258
308
  const toInsert = [];
259
309
  const toUpdate = [];
@@ -283,7 +333,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
283
333
  }
284
334
  async getByFilter(filter, user) {
285
335
  if (!this.isEnabled('getByFilter')) {
286
- throw new _exceptions.ForbiddenException(`Endpoint 'getByFilter' is disabled`);
336
+ throw new _exceptions.BaseAppException({
337
+ message: `Endpoint 'getByFilter' is disabled`,
338
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
339
+ messageVariables: {
340
+ endpoint: 'getByFilter'
341
+ },
342
+ status: _common.HttpStatus.FORBIDDEN
343
+ });
287
344
  }
288
345
  const result = await this.service.getAll('', {
289
346
  filter,
@@ -306,7 +363,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
306
363
  }
307
364
  async getAll(filterAndPaginationDto, user, search) {
308
365
  if (!this.isEnabled('getAll')) {
309
- throw new _exceptions.ForbiddenException(`Endpoint 'getAll' is disabled`);
366
+ throw new _exceptions.BaseAppException({
367
+ message: `Endpoint 'getAll' is disabled`,
368
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
369
+ messageVariables: {
370
+ endpoint: 'getAll'
371
+ },
372
+ status: _common.HttpStatus.FORBIDDEN
373
+ });
310
374
  }
311
375
  const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
312
376
  const data = (0, _classtransformer.plainToInstance)(responseDtoClass, result.data);
@@ -330,7 +394,14 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
330
394
  }
331
395
  async delete(deleteDto, user) {
332
396
  if (!this.isEnabled('delete')) {
333
- throw new _exceptions.ForbiddenException(`Endpoint 'delete' is disabled`);
397
+ throw new _exceptions.BaseAppException({
398
+ message: `Endpoint 'delete' is disabled`,
399
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
400
+ messageVariables: {
401
+ endpoint: 'delete'
402
+ },
403
+ status: _common.HttpStatus.FORBIDDEN
404
+ });
334
405
  }
335
406
  await this.service.delete(deleteDto, user);
336
407
  const count = Array.isArray(deleteDto.id) ? deleteDto.id.length : 1;
@@ -125,7 +125,7 @@ let ApiService = class ApiService {
125
125
  const result = this.convertEntityListToResponseListDto(output, isRaw);
126
126
  if (!result || !result.length) throw new _common.NotFoundException({
127
127
  message: 'No Data Found',
128
- messageKey: _constants.SYSTEM_MESSAGES.NOT_FOUND
128
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
129
129
  });
130
130
  return result;
131
131
  } catch (error) {
@@ -159,7 +159,7 @@ let ApiService = class ApiService {
159
159
  output = await finalQuery.getOne();
160
160
  if (!output) throw new _common.NotFoundException({
161
161
  message: 'No Data Found',
162
- messageKey: _constants.SYSTEM_MESSAGES.NOT_FOUND
162
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
163
163
  });
164
164
  result = this.convertEntityToResponseDto(output, false);
165
165
  }
@@ -249,18 +249,20 @@ let ApiService = class ApiService {
249
249
  `;
250
250
  const parameters = rawSubQuery.getParameters();
251
251
  const orderedValues = [];
252
+ const isPostgres = this.repository.manager.connection.options.type === 'postgres';
253
+ let paramIndex = 0;
252
254
  const convertedQuery = countSql.replace(/:(\w+)/g, (_, key)=>{
253
255
  if (!(key in parameters)) {
254
256
  throw new _common.InternalServerErrorException({
255
257
  message: `Missing parameter value for: ${key}`,
256
258
  messageKey: _constants.SYSTEM_MESSAGES.MISSING_PARAMETER,
257
- messageParams: {
259
+ messageVariables: {
258
260
  key
259
261
  }
260
262
  });
261
263
  }
262
264
  orderedValues.push(parameters[key]);
263
- return '?';
265
+ return isPostgres ? `$${++paramIndex}` : '?';
264
266
  });
265
267
  const result = await this.repository.query(convertedQuery, orderedValues);
266
268
  total = Number(result[0]?.count || 0);
@@ -337,7 +339,7 @@ let ApiService = class ApiService {
337
339
  }
338
340
  throw new _common.InternalServerErrorException({
339
341
  message: typeof error === 'string' ? error : 'Unknown error',
340
- messageKey: _constants.SYSTEM_MESSAGES.INTERNAL_ERROR
342
+ messageKey: _constants.ERROR_MESSAGES.INTERNAL
341
343
  });
342
344
  }
343
345
  /** Ensures value is always an array */ ensureArray(value) {
@@ -437,7 +439,7 @@ let ApiService = class ApiService {
437
439
  });
438
440
  if (!existing) throw new _common.NotFoundException({
439
441
  message: 'No such entity data found for update! Please, Try Again.',
440
- messageKey: _constants.SYSTEM_MESSAGES.NOT_FOUND
442
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
441
443
  });
442
444
  return Object.assign(existing, d);
443
445
  }
@@ -6,7 +6,6 @@ _export_star(require("./api-controller.class"), exports);
6
6
  _export_star(require("./api-service.class"), exports);
7
7
  _export_star(require("./request-scoped-api.service"), exports);
8
8
  _export_star(require("./hybrid-cache.class"), exports);
9
- _export_star(require("./winston-logger-adapter.class"), exports);
10
9
  _export_star(require("./winston.logger.class"), exports);
11
10
  _export_star(require("../constants/permissions"), exports);
12
11
  function _export_star(from, to) {
@@ -25,9 +25,6 @@ _export(exports, {
25
25
  get IS_PUBLIC_KEY () {
26
26
  return IS_PUBLIC_KEY;
27
27
  },
28
- get LOGGER_INSTANCE () {
29
- return LOGGER_INSTANCE;
30
- },
31
28
  get PERMISSIONS_CACHE_PREFIX () {
32
29
  return PERMISSIONS_CACHE_PREFIX;
33
30
  },
@@ -60,7 +57,6 @@ const IS_PUBLIC_KEY = 'isPublic';
60
57
  const PERMISSIONS_KEY = 'permissions';
61
58
  const CACHE_INSTANCE = 'CACHE_INSTANCE';
62
59
  const PERMISSION_GUARD_CONFIG = 'PERMISSION_GUARD_CONFIG';
63
- const LOGGER_INSTANCE = 'LOGGER_INSTANCE';
64
60
  const IDEMPOTENCY_KEY_HEADER = 'x-idempotency-key';
65
61
  const REQUEST_ID_HEADER = 'x-request-id';
66
62
  const CLIENT_TYPE_HEADER = 'x-client-type';
@@ -1,13 +1,3 @@
1
- // ==================== SHARED/SYSTEM MESSAGE KEYS ====================
2
- // Package-specific messages are now in their respective packages:
3
- // - nestjs-auth/src/config/message-keys.ts
4
- // - nestjs-iam/src/config/message-keys.ts
5
- // - nestjs-storage/src/config/message-keys.ts
6
- // - nestjs-email/src/config/message-keys.ts
7
- // - nestjs-form-builder/src/config/message-keys.ts
8
- // - nestjs-event-manager/src/config/message-keys.ts
9
- // - nestjs-notification/src/config/message-keys.ts
10
- // - nestjs-localization/src/config/message-keys.ts
11
1
  // ==================== AUTH (Shared across guards/interceptors) ====================
12
2
  // These are duplicated in nestjs-auth but needed here to avoid circular dependencies
13
3
  "use strict";
@@ -27,9 +17,6 @@ _export(exports, {
27
17
  get ERROR_MESSAGES () {
28
18
  return ERROR_MESSAGES;
29
19
  },
30
- get MESSAGE_KEYS () {
31
- return MESSAGE_KEYS;
32
- },
33
20
  get SYSTEM_MESSAGES () {
34
21
  return SYSTEM_MESSAGES;
35
22
  }
@@ -37,7 +24,7 @@ _export(exports, {
37
24
  const AUTH_MESSAGES = {
38
25
  TOKEN_REQUIRED: 'auth.token.required',
39
26
  TOKEN_INVALID: 'auth.token.invalid',
40
- TOKEN_EXPIRED: 'auth.token.expired',
27
+ ENTITY_BELOG_ANOTHER_COMPANY: 'entity.belongs.another.company',
41
28
  COMPANY_NO_ACCESS: 'auth.company.no.access'
42
29
  };
43
30
  const ERROR_MESSAGES = {
@@ -54,7 +41,8 @@ const ERROR_MESSAGES = {
54
41
  PERMISSION_SYSTEM_UNAVAILABLE: 'error.permission.system.unavailable',
55
42
  INSUFFICIENT_PERMISSIONS: 'error.insufficient.permissions',
56
43
  INSUFFICIENT_PERMISSIONS_OR: 'error.insufficient.permissions.or',
57
- NO_PERMISSIONS_FOUND: 'error.no.permissions.found'
44
+ NO_PERMISSIONS_FOUND: 'error.no.permissions.found',
45
+ ENDPOINT_DISABLED: 'error.endpoint.disabled'
58
46
  };
59
47
  const SYSTEM_MESSAGES = {
60
48
  REPOSITORY_NOT_AVAILABLE: 'system.repository.not.available',
@@ -63,7 +51,6 @@ const SYSTEM_MESSAGES = {
63
51
  SERVICE_NOT_AVAILABLE: 'system.service.not.available',
64
52
  CONFIG_REQUIRED: 'system.config.required',
65
53
  INTERNAL_ERROR: 'system.internal.error',
66
- NOT_FOUND: 'system.not.found',
67
54
  DUPLICATE_REQUEST: 'system.duplicate.request',
68
55
  INVALID_TENANT_ID: 'system.invalid.tenant.id',
69
56
  TENANT_NOT_FOUND: 'system.tenant.not.found',
@@ -73,8 +60,3 @@ const SYSTEM_MESSAGES = {
73
60
  PATH_TRAVERSAL_DETECTED: 'system.path.traversal.detected',
74
61
  INVALID_FILE_KEY: 'system.invalid.file.key'
75
62
  };
76
- const MESSAGE_KEYS = {
77
- AUTH: AUTH_MESSAGES,
78
- ERROR: ERROR_MESSAGES,
79
- SYSTEM: SYSTEM_MESSAGES
80
- };
@@ -28,9 +28,6 @@ _export(exports, {
28
28
  get EMAIL_TEMPLATE_PERMISSIONS () {
29
29
  return EMAIL_TEMPLATE_PERMISSIONS;
30
30
  },
31
- get EVENT_PARTICIPANT_PERMISSIONS () {
32
- return EVENT_PARTICIPANT_PERMISSIONS;
33
- },
34
31
  get EVENT_PERMISSIONS () {
35
32
  return EVENT_PERMISSIONS;
36
33
  },
@@ -174,12 +171,6 @@ const EVENT_PERMISSIONS = {
174
171
  UPDATE: 'event.update',
175
172
  DELETE: 'event.delete'
176
173
  };
177
- const EVENT_PARTICIPANT_PERMISSIONS = {
178
- CREATE: 'event-participant.create',
179
- READ: 'event-participant.read',
180
- UPDATE: 'event-participant.update',
181
- DELETE: 'event-participant.delete'
182
- };
183
174
  const NOTIFICATION_PERMISSIONS = {
184
175
  CREATE: 'notification.create',
185
176
  READ: 'notification.read',
@@ -228,7 +219,6 @@ const PERMISSIONS = {
228
219
  FORM_RESULT: FORM_RESULT_PERMISSIONS,
229
220
  // Event Manager
230
221
  EVENT: EVENT_PERMISSIONS,
231
- EVENT_PARTICIPANT: EVENT_PARTICIPANT_PERMISSIONS,
232
222
  // Notification
233
223
  NOTIFICATION: NOTIFICATION_PERMISSIONS,
234
224
  // Localization
@@ -12,10 +12,9 @@ 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')=>{
15
- // Select appropriate wrapper based on response type
16
15
  let wrapperDto;
17
16
  let metaDto = null;
18
- if (!isArray) {
17
+ if (!isArray || arrayType === 'single') {
19
18
  wrapperDto = _dtos.SingleResponseDto;
20
19
  } else if (arrayType === 'bulk') {
21
20
  wrapperDto = _dtos.BulkResponseDto;
@@ -7,7 +7,6 @@ _export_star(require("./current-user.decorator"), exports);
7
7
  _export_star(require("./log-action.decorator"), exports);
8
8
  _export_star(require("./public.decorator"), exports);
9
9
  _export_star(require("./require-permission.decorator"), exports);
10
- _export_star(require("./sanitize-html.decorator"), exports);
11
10
  function _export_star(from, to) {
12
11
  Object.keys(from).forEach(function(k) {
13
12
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -15,9 +15,6 @@ _export(exports, {
15
15
  get RequirePermission () {
16
16
  return RequirePermission;
17
17
  },
18
- get RequirePermissionCondition () {
19
- return RequirePermissionCondition;
20
- },
21
18
  get RequirePermissionLogic () {
22
19
  return RequirePermissionLogic;
23
20
  }
@@ -33,4 +30,3 @@ const RequireAnyPermission = (...permissions)=>(0, _common.SetMetadata)(_constan
33
30
  operator: 'OR'
34
31
  });
35
32
  const RequirePermissionLogic = (logic)=>(0, _common.SetMetadata)(_constants.PERMISSIONS_KEY, logic);
36
- const RequirePermissionCondition = RequirePermissionLogic;
@@ -56,11 +56,11 @@ let BaseAppException = class BaseAppException extends _common.HttpException {
56
56
  success: false,
57
57
  message: options.message,
58
58
  messageKey: options.messageKey || _messagekeys.ERROR_MESSAGES.GENERIC,
59
- messageParams: options.messageParams,
59
+ messageVariables: options.messageVariables,
60
60
  errors: options.errors
61
- }, status), _define_property(this, "messageKey", void 0), _define_property(this, "messageParams", void 0), _define_property(this, "errors", void 0), _define_property(this, "metadata", void 0);
61
+ }, status), _define_property(this, "messageKey", void 0), _define_property(this, "messageVariables", void 0), _define_property(this, "errors", void 0), _define_property(this, "metadata", void 0);
62
62
  this.messageKey = options.messageKey || _messagekeys.ERROR_MESSAGES.GENERIC;
63
- this.messageParams = options.messageParams;
63
+ this.messageVariables = options.messageVariables;
64
64
  this.errors = options.errors;
65
65
  this.metadata = options.metadata;
66
66
  }
@@ -133,7 +133,7 @@ let ServiceUnavailableException = class ServiceUnavailableException extends Base
133
133
  super({
134
134
  message: `${service} is temporarily unavailable`,
135
135
  messageKey: _messagekeys.ERROR_MESSAGES.SERVICE_UNAVAILABLE,
136
- messageParams: {
136
+ messageVariables: {
137
137
  service
138
138
  },
139
139
  status: _common.HttpStatus.SERVICE_UNAVAILABLE,
@@ -37,7 +37,7 @@ let InsufficientPermissionsException = class InsufficientPermissionsException ex
37
37
  success: false,
38
38
  message: 'Insufficient permissions',
39
39
  messageKey,
40
- messageParams: {
40
+ messageVariables: {
41
41
  permissions: missingPermissions.join(', ')
42
42
  },
43
43
  missingPermissions,
@@ -71,7 +71,7 @@ let GlobalExceptionFilter = class GlobalExceptionFilter {
71
71
  success: false,
72
72
  message: exception.message,
73
73
  messageKey: exception.messageKey,
74
- messageParams: exception.messageParams,
74
+ messageVariables: exception.messageVariables,
75
75
  errors: exception.errors,
76
76
  _meta: {
77
77
  requestId,
@@ -82,12 +82,12 @@ let GlobalExceptionFilter = class GlobalExceptionFilter {
82
82
  }
83
83
  if (exception instanceof _common.HttpException) {
84
84
  const response = exception.getResponse();
85
- const { message, messageKey, messageParams, errors } = this.extractHttpExceptionDetails(response);
85
+ const { message, messageKey, messageVariables, errors } = this.extractHttpExceptionDetails(response);
86
86
  return {
87
87
  success: false,
88
88
  message,
89
89
  messageKey,
90
- messageParams,
90
+ messageVariables,
91
91
  errors,
92
92
  _meta: {
93
93
  requestId,
@@ -134,7 +134,7 @@ let GlobalExceptionFilter = class GlobalExceptionFilter {
134
134
  return {
135
135
  message: String(obj.message || 'Unknown error'),
136
136
  messageKey: String(obj.messageKey || _messagekeys.ERROR_MESSAGES.HTTP),
137
- messageParams: obj.messageParams,
137
+ messageVariables: obj.messageVariables,
138
138
  errors: obj.errors
139
139
  };
140
140
  }
@@ -7,7 +7,6 @@ _export_star(require("./datasource.interface"), exports);
7
7
  _export_star(require("./event-manager-adapter.interface"), exports);
8
8
  _export_star(require("./identity.interface"), exports);
9
9
  _export_star(require("./logged-user-info.interface"), exports);
10
- _export_star(require("./logger.interface"), exports);
11
10
  _export_star(require("./module-config.interface"), exports);
12
11
  _export_star(require("./notification-adapter.interface"), exports);
13
12
  _export_star(require("./permission.interface"), exports);
@@ -98,7 +98,7 @@ let MultiTenantDataSourceService = class MultiTenantDataSourceService {
98
98
  throw new _common.BadRequestException({
99
99
  message: `Tenant '${tenantId}' not found`,
100
100
  messageKey: _constants.SYSTEM_MESSAGES.TENANT_NOT_FOUND,
101
- messageParams: {
101
+ messageVariables: {
102
102
  tenantId
103
103
  }
104
104
  });
@@ -193,7 +193,7 @@ let MultiTenantDataSourceService = class MultiTenantDataSourceService {
193
193
  throw new _common.BadRequestException({
194
194
  message: `Tenant not found. Ensure '${this.tenantHeader}' header is set.`,
195
195
  messageKey: _constants.SYSTEM_MESSAGES.TENANT_HEADER_REQUIRED,
196
- messageParams: {
196
+ messageVariables: {
197
197
  header: this.tenantHeader
198
198
  }
199
199
  });
@@ -0,0 +1,94 @@
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 formatInTimezone () {
13
+ return formatInTimezone;
14
+ },
15
+ get getTodayInTimezone () {
16
+ return getTodayInTimezone;
17
+ },
18
+ get localToUtc () {
19
+ return localToUtc;
20
+ },
21
+ get utcToLocal () {
22
+ return utcToLocal;
23
+ }
24
+ });
25
+ function getOffsetMinutes(utcDate, timezone) {
26
+ const extract = (tz)=>{
27
+ const parts = new Intl.DateTimeFormat('en-US', {
28
+ timeZone: tz,
29
+ year: 'numeric',
30
+ month: '2-digit',
31
+ day: '2-digit',
32
+ hour: '2-digit',
33
+ minute: '2-digit',
34
+ second: '2-digit',
35
+ hour12: false
36
+ }).formatToParts(utcDate);
37
+ const p = Object.fromEntries(parts.filter((x)=>x.type !== 'literal').map((x)=>[
38
+ x.type,
39
+ parseInt(x.value)
40
+ ]));
41
+ return Date.UTC(p['year'], p['month'] - 1, p['day'], p['hour'], p['minute'], p['second']);
42
+ };
43
+ return (extract(timezone) - extract('UTC')) / 60_000;
44
+ }
45
+ function localToUtc(dateStr, timeStr, timezone) {
46
+ const [year, month, day] = dateStr.split('-').map(Number);
47
+ const [hours, minutes] = timeStr.split(':').map(Number);
48
+ const approx = new Date(Date.UTC(year, month - 1, day, hours, minutes, 0));
49
+ const offset = getOffsetMinutes(approx, timezone);
50
+ const utcDate = new Date(approx.getTime() - offset * 60_000);
51
+ // DST boundary guard: re-check offset after adjustment
52
+ const finalOffset = getOffsetMinutes(utcDate, timezone);
53
+ return finalOffset !== offset ? new Date(approx.getTime() - finalOffset * 60_000) : utcDate;
54
+ }
55
+ function utcToLocal(utcDate, timezone) {
56
+ const d = typeof utcDate === 'string' ? new Date(utcDate) : utcDate;
57
+ const parts = new Intl.DateTimeFormat('en-CA', {
58
+ timeZone: timezone,
59
+ year: 'numeric',
60
+ month: '2-digit',
61
+ day: '2-digit',
62
+ hour: '2-digit',
63
+ minute: '2-digit',
64
+ hour12: false
65
+ }).formatToParts(d);
66
+ const p = Object.fromEntries(parts.filter((x)=>x.type !== 'literal').map((x)=>[
67
+ x.type,
68
+ x.value
69
+ ]));
70
+ // en-CA formats midnight hour as '24' — normalize to '00'
71
+ const hour = p['hour'] === '24' ? '00' : p['hour'];
72
+ return {
73
+ date: `${p['year']}-${p['month']}-${p['day']}`,
74
+ time: `${hour}:${p['minute']}`,
75
+ display: new Intl.DateTimeFormat('en-US', {
76
+ timeZone: timezone,
77
+ dateStyle: 'medium',
78
+ timeStyle: 'short'
79
+ }).format(d)
80
+ };
81
+ }
82
+ function formatInTimezone(utcDate, timezone, options = {
83
+ dateStyle: 'medium',
84
+ timeStyle: 'short'
85
+ }) {
86
+ const d = typeof utcDate === 'string' ? new Date(utcDate) : utcDate;
87
+ return new Intl.DateTimeFormat('en-US', {
88
+ ...options,
89
+ timeZone: timezone
90
+ }).format(d);
91
+ }
92
+ function getTodayInTimezone(timezone) {
93
+ return utcToLocal(new Date(), timezone).date;
94
+ }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ _export_star(require("./date-time.util"), exports);
5
6
  _export_star(require("./html-sanitizer.util"), exports);
6
7
  _export_star(require("./query-helpers.util"), exports);
7
8
  _export_star(require("./request.util"), exports);
@@ -50,8 +50,8 @@ function validateCompanyOwnership(entity, user, isCompanyFeatureEnabled, entityN
50
50
  if (entity.companyId && entity.companyId !== user.companyId) {
51
51
  throw new _common.BadRequestException({
52
52
  message: `${entityName} belongs to another company`,
53
- messageKey: _constants.AUTH_MESSAGES.COMPANY_NO_ACCESS,
54
- messageParams: {
53
+ messageKey: _constants.AUTH_MESSAGES.ENTITY_BELOG_ANOTHER_COMPANY,
54
+ messageVariables: {
55
55
  entity: entityName
56
56
  }
57
57
  });
@@ -12,6 +12,12 @@ _export(exports, {
12
12
  get buildCookieOptions () {
13
13
  return buildCookieOptions;
14
14
  },
15
+ get buildFrontendUrl () {
16
+ return buildFrontendUrl;
17
+ },
18
+ get extractFrontendUrl () {
19
+ return extractFrontendUrl;
20
+ },
15
21
  get isBrowserRequest () {
16
22
  return isBrowserRequest;
17
23
  },
@@ -69,3 +75,22 @@ function parseDurationToMs(duration, defaultMs = TIME_UNIT_MS.w) {
69
75
  const unit = match[2];
70
76
  return value * (TIME_UNIT_MS[unit] ?? TIME_UNIT_MS.d);
71
77
  }
78
+ function extractFrontendUrl(req) {
79
+ const allowedOrigins = _config.envConfig.getOrigins();
80
+ const origin = (req.get('origin') ?? req.get('referer') ?? '').trim();
81
+ if (origin && allowedOrigins.length) {
82
+ const matched = allowedOrigins.find((u)=>origin.startsWith(u));
83
+ if (matched) {
84
+ return matched;
85
+ }
86
+ }
87
+ const host = req.get('host');
88
+ if (!host) {
89
+ throw new Error('Unable to determine frontend URL from request');
90
+ }
91
+ return `${req.protocol}://${host}`;
92
+ }
93
+ function buildFrontendUrl(req, path) {
94
+ const baseUrl = extractFrontendUrl(req);
95
+ return `${baseUrl}${path}`;
96
+ }
@@ -2,6 +2,5 @@ export * from './api-controller.class';
2
2
  export * from './api-service.class';
3
3
  export * from './request-scoped-api.service';
4
4
  export * from './hybrid-cache.class';
5
- export * from './winston-logger-adapter.class';
6
5
  export * from './winston.logger.class';
7
6
  export * from '../constants/permissions';
@@ -2,7 +2,6 @@ export declare const IS_PUBLIC_KEY = "isPublic";
2
2
  export declare const PERMISSIONS_KEY = "permissions";
3
3
  export declare const CACHE_INSTANCE = "CACHE_INSTANCE";
4
4
  export declare const PERMISSION_GUARD_CONFIG = "PERMISSION_GUARD_CONFIG";
5
- export declare const LOGGER_INSTANCE = "LOGGER_INSTANCE";
6
5
  export declare const IDEMPOTENCY_KEY_HEADER = "x-idempotency-key";
7
6
  export declare const REQUEST_ID_HEADER = "x-request-id";
8
7
  export declare const CLIENT_TYPE_HEADER = "x-client-type";