@flusys/nestjs-notification 7.0.2 → 8.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/adapters/index.d.ts +1 -1
  2. package/adapters/notification.adapter.d.ts +2 -2
  3. package/config/index.d.ts +3 -3
  4. package/controllers/index.d.ts +1 -1
  5. package/controllers/notification.controller.d.ts +4 -4
  6. package/docs/index.d.ts +1 -1
  7. package/docs/notification-swagger.config.d.ts +2 -2
  8. package/dtos/index.d.ts +1 -1
  9. package/entities/index.d.ts +5 -5
  10. package/entities/notification-with-company.entity.d.ts +1 -1
  11. package/fesm/244.js +816 -0
  12. package/fesm/446.js +939 -0
  13. package/fesm/adapters/index.js +79 -1
  14. package/fesm/config/index.js +84 -3
  15. package/fesm/controllers/index.js +13 -1
  16. package/fesm/docs/index.js +112 -1
  17. package/fesm/dtos/index.js +311 -1
  18. package/fesm/entities/index.js +211 -8
  19. package/fesm/gateways/index.js +286 -1
  20. package/fesm/index.js +467 -10
  21. package/fesm/interfaces/index.js +16 -2
  22. package/fesm/modules/index.js +269 -1
  23. package/fesm/runtime.js +85 -0
  24. package/fesm/services/index.js +357 -4
  25. package/gateways/index.d.ts +1 -1
  26. package/gateways/notification.gateway.d.ts +2 -2
  27. package/index.d.ts +10 -10
  28. package/interfaces/index.d.ts +2 -2
  29. package/interfaces/notification-module.interface.d.ts +3 -3
  30. package/interfaces/notification.interface.d.ts +1 -1
  31. package/modules/index.d.ts +1 -1
  32. package/modules/notification.module.d.ts +2 -2
  33. package/package.json +33 -44
  34. package/services/index.d.ts +4 -4
  35. package/services/notification-config.service.d.ts +3 -3
  36. package/services/notification-datasource.provider.d.ts +3 -3
  37. package/services/notification-helper.service.d.ts +5 -5
  38. package/services/notification.service.d.ts +8 -8
  39. package/cjs/adapters/index.js +0 -18
  40. package/cjs/adapters/notification.adapter.js +0 -62
  41. package/cjs/adapters/notification.adapter.spec.js +0 -73
  42. package/cjs/config/event-actions.js +0 -33
  43. package/cjs/config/index.js +0 -20
  44. package/cjs/config/message-keys.js +0 -19
  45. package/cjs/config/notification.constants.js +0 -11
  46. package/cjs/controllers/index.js +0 -18
  47. package/cjs/controllers/notification.controller.js +0 -299
  48. package/cjs/controllers/notification.controller.spec.js +0 -214
  49. package/cjs/docs/index.js +0 -18
  50. package/cjs/docs/notification-swagger.config.js +0 -97
  51. package/cjs/docs/notification-swagger.config.spec.js +0 -68
  52. package/cjs/dtos/index.js +0 -18
  53. package/cjs/dtos/notification.dto.js +0 -295
  54. package/cjs/entities/index.js +0 -48
  55. package/cjs/entities/index.spec.js +0 -13
  56. package/cjs/entities/notification-with-company.entity.js +0 -57
  57. package/cjs/entities/notification.entity.js +0 -112
  58. package/cjs/gateways/index.js +0 -18
  59. package/cjs/gateways/notification.gateway.js +0 -172
  60. package/cjs/gateways/notification.gateway.spec.js +0 -359
  61. package/cjs/index.js +0 -28
  62. package/cjs/interfaces/index.js +0 -19
  63. package/cjs/interfaces/notification-module.interface.js +0 -4
  64. package/cjs/interfaces/notification.interface.js +0 -4
  65. package/cjs/modules/index.js +0 -18
  66. package/cjs/modules/notification.module.js +0 -139
  67. package/cjs/modules/notification.module.spec.js +0 -152
  68. package/cjs/services/index.js +0 -21
  69. package/cjs/services/notification-config.service.js +0 -69
  70. package/cjs/services/notification-config.service.spec.js +0 -113
  71. package/cjs/services/notification-datasource.provider.js +0 -133
  72. package/cjs/services/notification-datasource.provider.spec.js +0 -136
  73. package/cjs/services/notification-helper.service.js +0 -197
  74. package/cjs/services/notification-helper.service.spec.js +0 -392
  75. package/cjs/services/notification.service.js +0 -281
  76. package/cjs/services/notification.service.spec.js +0 -560
  77. package/fesm/adapters/notification.adapter.js +0 -52
  78. package/fesm/adapters/notification.adapter.spec.js +0 -69
  79. package/fesm/config/event-actions.js +0 -12
  80. package/fesm/config/message-keys.js +0 -9
  81. package/fesm/config/notification.constants.js +0 -1
  82. package/fesm/controllers/notification.controller.js +0 -289
  83. package/fesm/controllers/notification.controller.spec.js +0 -210
  84. package/fesm/docs/notification-swagger.config.js +0 -87
  85. package/fesm/docs/notification-swagger.config.spec.js +0 -64
  86. package/fesm/dtos/notification.dto.js +0 -262
  87. package/fesm/entities/index.spec.js +0 -9
  88. package/fesm/entities/notification-with-company.entity.js +0 -47
  89. package/fesm/entities/notification.entity.js +0 -102
  90. package/fesm/gateways/notification.gateway.js +0 -162
  91. package/fesm/gateways/notification.gateway.spec.js +0 -355
  92. package/fesm/interfaces/notification-module.interface.js +0 -1
  93. package/fesm/interfaces/notification.interface.js +0 -1
  94. package/fesm/modules/notification.module.js +0 -129
  95. package/fesm/modules/notification.module.spec.js +0 -148
  96. package/fesm/services/notification-config.service.js +0 -59
  97. package/fesm/services/notification-config.service.spec.js +0 -109
  98. package/fesm/services/notification-datasource.provider.js +0 -82
  99. package/fesm/services/notification-datasource.provider.spec.js +0 -132
  100. package/fesm/services/notification-helper.service.js +0 -187
  101. package/fesm/services/notification-helper.service.spec.js +0 -388
  102. package/fesm/services/notification.service.js +0 -271
  103. package/fesm/services/notification.service.spec.js +0 -556
@@ -1,392 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- const _testing = require("@nestjs/testing");
6
- const _classes = require("@flusys/nestjs-shared/classes");
7
- const _modules = require("@flusys/nestjs-shared/modules");
8
- const _enums = require("@flusys/nestjs-shared/enums");
9
- const _notificationhelperservice = require("./notification-helper.service");
10
- const _notificationconfigservice = require("./notification-config.service");
11
- const _notificationdatasourceprovider = require("./notification-datasource.provider");
12
- const _gateways = require("../gateways");
13
- const _entities = require("../entities");
14
- function createMockRepo() {
15
- return {
16
- save: jest.fn()
17
- };
18
- }
19
- function createMockDataSource(repo) {
20
- return {
21
- getRepository: jest.fn().mockReturnValue(repo)
22
- };
23
- }
24
- describe('NotificationHelperService', ()=>{
25
- let mockCacheManager;
26
- let mockUtilsService;
27
- let mockConfigService;
28
- let mockDataSourceProvider;
29
- let mockGateway;
30
- let mockRepo;
31
- let mockDataSource;
32
- async function buildService(withGateway = true) {
33
- const providers = [
34
- _notificationhelperservice.NotificationHelperService,
35
- {
36
- provide: 'CACHE_INSTANCE',
37
- useValue: mockCacheManager
38
- },
39
- {
40
- provide: _modules.UtilsService,
41
- useValue: mockUtilsService
42
- },
43
- {
44
- provide: _notificationconfigservice.NotificationConfigService,
45
- useValue: mockConfigService
46
- },
47
- {
48
- provide: _notificationdatasourceprovider.NotificationDataSourceProvider,
49
- useValue: mockDataSourceProvider
50
- }
51
- ];
52
- if (withGateway) {
53
- providers.push({
54
- provide: _gateways.NotificationGateway,
55
- useValue: mockGateway
56
- });
57
- }
58
- const module = await _testing.Test.createTestingModule({
59
- providers
60
- }).compile();
61
- return module.get(_notificationhelperservice.NotificationHelperService);
62
- }
63
- beforeEach(()=>{
64
- mockRepo = createMockRepo();
65
- mockDataSource = createMockDataSource(mockRepo);
66
- mockCacheManager = {};
67
- mockUtilsService = {
68
- clearCache: jest.fn().mockResolvedValue(undefined)
69
- };
70
- mockConfigService = {
71
- isCompanyFeatureEnabled: jest.fn().mockReturnValue(false)
72
- };
73
- mockDataSourceProvider = {
74
- getDataSource: jest.fn().mockResolvedValue(mockDataSource)
75
- };
76
- mockGateway = {
77
- emitToUser: jest.fn(),
78
- emitToUserInCompany: jest.fn(),
79
- isUserOnline: jest.fn(),
80
- getOnlineUserCount: jest.fn()
81
- };
82
- });
83
- describe('send', ()=>{
84
- it('saves the notification, clears the cache, and emits to the user in real time', async ()=>{
85
- const service = await buildService();
86
- const options = {
87
- userId: 'user-1',
88
- title: 'Hi',
89
- message: 'body',
90
- type: _enums.NotificationType.SUCCESS,
91
- data: {
92
- a: 1
93
- }
94
- };
95
- const saved = {
96
- id: 'notif-1',
97
- ...options,
98
- isRead: false
99
- };
100
- mockRepo.save.mockResolvedValue(saved);
101
- const result = await service.send(options);
102
- expect(mockDataSource.getRepository).toHaveBeenCalledWith(_entities.Notification);
103
- expect(mockRepo.save).toHaveBeenCalledWith(expect.objectContaining({
104
- userId: 'user-1',
105
- title: 'Hi',
106
- isRead: false
107
- }));
108
- expect(mockUtilsService.clearCache).toHaveBeenCalledWith('notification', mockCacheManager);
109
- expect(mockGateway.emitToUser).toHaveBeenCalledWith('user-1', 'notification:new', expect.objectContaining({
110
- id: 'notif-1',
111
- title: 'Hi'
112
- }));
113
- expect(result).toBe(saved);
114
- });
115
- it('defaults type to INFO and message/data to null when omitted', async ()=>{
116
- const service = await buildService();
117
- mockRepo.save.mockImplementation(async (entity)=>({
118
- id: 'notif-2',
119
- ...entity
120
- }));
121
- await service.send({
122
- userId: 'user-1',
123
- title: 'Only title'
124
- });
125
- expect(mockRepo.save).toHaveBeenCalledWith(expect.objectContaining({
126
- type: _enums.NotificationType.INFO,
127
- message: null,
128
- data: null
129
- }));
130
- });
131
- it('does not emit in real time when realtime is explicitly false', async ()=>{
132
- const service = await buildService();
133
- mockRepo.save.mockResolvedValue({
134
- id: 'notif-3',
135
- userId: 'user-1',
136
- title: 'Silent'
137
- });
138
- await service.send({
139
- userId: 'user-1',
140
- title: 'Silent',
141
- realtime: false
142
- });
143
- expect(mockGateway.emitToUser).not.toHaveBeenCalled();
144
- expect(mockGateway.emitToUserInCompany).not.toHaveBeenCalled();
145
- });
146
- it('does not throw when no gateway is bound (gateway not registered)', async ()=>{
147
- const service = await buildService(false);
148
- mockRepo.save.mockResolvedValue({
149
- id: 'notif-4',
150
- userId: 'user-1',
151
- title: 'No gateway'
152
- });
153
- await expect(service.send({
154
- userId: 'user-1',
155
- title: 'No gateway'
156
- })).resolves.toBeDefined();
157
- });
158
- it('uses NotificationWithCompany and includes companyId when the company feature is enabled', async ()=>{
159
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(true);
160
- const service = await buildService();
161
- mockRepo.save.mockImplementation(async (entity)=>({
162
- id: 'notif-5',
163
- ...entity
164
- }));
165
- await service.send({
166
- userId: 'user-1',
167
- title: 'Scoped',
168
- companyId: 'company-1'
169
- });
170
- expect(mockDataSource.getRepository).toHaveBeenCalledWith(_entities.NotificationWithCompany);
171
- expect(mockRepo.save).toHaveBeenCalledWith(expect.objectContaining({
172
- companyId: 'company-1'
173
- }));
174
- expect(mockGateway.emitToUserInCompany).toHaveBeenCalledWith('user-1', 'company-1', 'notification:new', expect.any(Object));
175
- });
176
- it('omits companyId when the company feature is enabled but none was provided', async ()=>{
177
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(true);
178
- const service = await buildService();
179
- mockRepo.save.mockImplementation(async (entity)=>({
180
- id: 'notif-6',
181
- ...entity
182
- }));
183
- await service.send({
184
- userId: 'user-1',
185
- title: 'No company'
186
- });
187
- const savedArg = mockRepo.save.mock.calls[0][0];
188
- expect(savedArg.companyId).toBeUndefined();
189
- });
190
- it('reuses the same cached data source across multiple calls', async ()=>{
191
- const service = await buildService();
192
- mockRepo.save.mockResolvedValue({
193
- id: 'notif-7',
194
- userId: 'user-1',
195
- title: 'A'
196
- });
197
- await service.send({
198
- userId: 'user-1',
199
- title: 'A'
200
- });
201
- await service.send({
202
- userId: 'user-1',
203
- title: 'B'
204
- });
205
- expect(mockDataSourceProvider.getDataSource).toHaveBeenCalledTimes(1);
206
- });
207
- });
208
- describe('sendToMany', ()=>{
209
- it('saves a notification for every user id and clears the cache once', async ()=>{
210
- const service = await buildService();
211
- const options = {
212
- userIds: [
213
- 'user-1',
214
- 'user-2',
215
- 'user-3'
216
- ],
217
- title: 'Broadcast'
218
- };
219
- mockRepo.save.mockImplementation(async (entities)=>entities.map((e, i)=>({
220
- id: `notif-${i}`,
221
- ...e
222
- })));
223
- const result = await service.sendToMany(options);
224
- expect(mockRepo.save).toHaveBeenCalledWith([
225
- expect.objectContaining({
226
- userId: 'user-1'
227
- }),
228
- expect.objectContaining({
229
- userId: 'user-2'
230
- }),
231
- expect.objectContaining({
232
- userId: 'user-3'
233
- })
234
- ]);
235
- expect(mockUtilsService.clearCache).toHaveBeenCalledTimes(1);
236
- expect(result).toHaveLength(3);
237
- });
238
- it('handles an empty userIds array without saving or emitting', async ()=>{
239
- const service = await buildService();
240
- mockRepo.save.mockResolvedValue([]);
241
- const result = await service.sendToMany({
242
- userIds: [],
243
- title: 'Nobody'
244
- });
245
- expect(mockRepo.save).toHaveBeenCalledWith([]);
246
- expect(result).toEqual([]);
247
- });
248
- it('emits to each user asynchronously (after the microtask queue flushes) when realtime', async ()=>{
249
- const service = await buildService();
250
- mockRepo.save.mockImplementation(async (entities)=>entities.map((e, i)=>({
251
- id: `notif-${i}`,
252
- ...e
253
- })));
254
- await service.sendToMany({
255
- userIds: [
256
- 'user-1',
257
- 'user-2'
258
- ],
259
- title: 'Broadcast'
260
- });
261
- expect(mockGateway.emitToUser).not.toHaveBeenCalled();
262
- await new Promise((resolve)=>setImmediate(resolve));
263
- expect(mockGateway.emitToUser).toHaveBeenCalledTimes(2);
264
- expect(mockGateway.emitToUser).toHaveBeenCalledWith('user-1', 'notification:new', expect.any(Object));
265
- expect(mockGateway.emitToUser).toHaveBeenCalledWith('user-2', 'notification:new', expect.any(Object));
266
- });
267
- it('does not schedule emits when realtime is false', async ()=>{
268
- const service = await buildService();
269
- mockRepo.save.mockImplementation(async (entities)=>entities.map((e, i)=>({
270
- id: `notif-${i}`,
271
- ...e
272
- })));
273
- await service.sendToMany({
274
- userIds: [
275
- 'user-1'
276
- ],
277
- title: 'Silent',
278
- realtime: false
279
- });
280
- await new Promise((resolve)=>setImmediate(resolve));
281
- expect(mockGateway.emitToUser).not.toHaveBeenCalled();
282
- });
283
- });
284
- describe('isUserOnline', ()=>{
285
- it('delegates to the gateway when present', async ()=>{
286
- const service = await buildService();
287
- mockGateway.isUserOnline.mockReturnValue(true);
288
- expect(service.isUserOnline('user-1')).toBe(true);
289
- expect(mockGateway.isUserOnline).toHaveBeenCalledWith('user-1');
290
- });
291
- it('returns false when no gateway is bound', async ()=>{
292
- const service = await buildService(false);
293
- expect(service.isUserOnline('user-1')).toBe(false);
294
- });
295
- });
296
- describe('getOnlineUserCount', ()=>{
297
- it('delegates to the gateway when present', async ()=>{
298
- const service = await buildService();
299
- mockGateway.getOnlineUserCount.mockReturnValue(5);
300
- expect(service.getOnlineUserCount()).toBe(5);
301
- });
302
- it('returns 0 when no gateway is bound', async ()=>{
303
- const service = await buildService(false);
304
- expect(service.getOnlineUserCount()).toBe(0);
305
- });
306
- });
307
- describe('domain events', ()=>{
308
- let publish;
309
- beforeEach(()=>{
310
- publish = jest.fn().mockResolvedValue(undefined);
311
- _classes.EventBusRegistry.reset();
312
- _classes.EventBusRegistry.setBus({
313
- publish,
314
- subscribe: jest.fn(),
315
- close: jest.fn()
316
- });
317
- _classes.EventBusRegistry.configureModule('notification', {
318
- enabled: true
319
- });
320
- });
321
- afterEach(()=>{
322
- _classes.EventBusRegistry.reset();
323
- });
324
- it('publishes notification.notification.sent for a single send', async ()=>{
325
- const service = await buildService();
326
- mockRepo.save.mockResolvedValue({
327
- id: 'notif-1',
328
- userId: 'user-1'
329
- });
330
- await service.send({
331
- userId: 'user-1',
332
- title: 'Hi'
333
- });
334
- expect(publish).toHaveBeenCalledWith(expect.objectContaining({
335
- name: 'notification.notification.sent',
336
- payload: expect.objectContaining({
337
- ids: [
338
- 'notif-1'
339
- ],
340
- metadata: expect.objectContaining({
341
- recipientCount: 1
342
- })
343
- })
344
- }));
345
- });
346
- it('reports the recipient count for a bulk send', async ()=>{
347
- const service = await buildService();
348
- mockRepo.save.mockResolvedValue([
349
- {
350
- id: 'notif-1',
351
- userId: 'user-1'
352
- },
353
- {
354
- id: 'notif-2',
355
- userId: 'user-2'
356
- }
357
- ]);
358
- await service.sendToMany({
359
- userIds: [
360
- 'user-1',
361
- 'user-2'
362
- ],
363
- title: 'Hi',
364
- realtime: false
365
- });
366
- expect(publish.mock.calls[0][0].payload).toEqual(expect.objectContaining({
367
- ids: [
368
- 'notif-1',
369
- 'notif-2'
370
- ],
371
- metadata: expect.objectContaining({
372
- recipientCount: 2
373
- })
374
- }));
375
- });
376
- it('does not publish when the notification module has events disabled', async ()=>{
377
- _classes.EventBusRegistry.configureModule('notification', {
378
- enabled: false
379
- });
380
- const service = await buildService();
381
- mockRepo.save.mockResolvedValue({
382
- id: 'notif-1',
383
- userId: 'user-1'
384
- });
385
- await service.send({
386
- userId: 'user-1',
387
- title: 'Hi'
388
- });
389
- expect(publish).not.toHaveBeenCalled();
390
- });
391
- });
392
- });
@@ -1,281 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "NotificationService", {
6
- enumerable: true,
7
- get: function() {
8
- return NotificationService;
9
- }
10
- });
11
- const _nestjsshared = require("@flusys/nestjs-shared");
12
- const _classes = require("@flusys/nestjs-shared/classes");
13
- const _interfaces = require("@flusys/nestjs-shared/interfaces");
14
- const _modules = require("@flusys/nestjs-shared/modules");
15
- const _utils = require("@flusys/nestjs-shared/utils");
16
- const _common = require("@nestjs/common");
17
- const _config = require("../config");
18
- const _entities = require("../entities");
19
- const _gateways = require("../gateways");
20
- const _notificationconfigservice = require("./notification-config.service");
21
- const _notificationdatasourceprovider = require("./notification-datasource.provider");
22
- function _define_property(obj, key, value) {
23
- if (key in obj) {
24
- Object.defineProperty(obj, key, {
25
- value: value,
26
- enumerable: true,
27
- configurable: true,
28
- writable: true
29
- });
30
- } else {
31
- obj[key] = value;
32
- }
33
- return obj;
34
- }
35
- function _ts_decorate(decorators, target, key, desc) {
36
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
37
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
38
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
39
- return c > 3 && r && Object.defineProperty(target, key, r), r;
40
- }
41
- function _ts_metadata(k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- }
44
- function _ts_param(paramIndex, decorator) {
45
- return function(target, key) {
46
- decorator(target, key, paramIndex);
47
- };
48
- }
49
- let NotificationService = class NotificationService extends _classes.ApiService {
50
- async convertSingleDtoToEntity(dto, user) {
51
- let entity = {};
52
- if ('id' in dto && dto.id) {
53
- const existing = await this.repository.findOne({
54
- where: {
55
- id: dto.id
56
- }
57
- });
58
- if (!existing) {
59
- throw new _common.NotFoundException({
60
- message: 'Notification not found',
61
- messageKey: _config.NOTIFICATION_MESSAGES.NOT_FOUND
62
- });
63
- }
64
- entity = existing;
65
- }
66
- const merged = {
67
- ...entity,
68
- userId: user?.id ?? entity.userId,
69
- type: dto.type ?? entity.type ?? 'info',
70
- title: dto.title ?? entity.title,
71
- message: dto.message ?? entity.message,
72
- data: dto.data ?? entity.data,
73
- isRead: entity.isRead ?? false,
74
- readAt: entity.readAt
75
- };
76
- if (this.notificationConfig.isCompanyFeatureEnabled()) {
77
- merged.companyId = dto.companyId ?? user?.companyId ?? entity.companyId ?? null;
78
- }
79
- return merged;
80
- }
81
- async getSelectQuery(query, _user, select) {
82
- const fields = select && select.length ? select : [];
83
- const always = [
84
- 'createdAt',
85
- 'updatedAt'
86
- ];
87
- const merged = [
88
- ...new Set([
89
- ...fields,
90
- ...always
91
- ])
92
- ];
93
- query.addSelect(merged.map((f)=>`${this.entityName}.${f}`));
94
- return {
95
- query,
96
- isRaw: false
97
- };
98
- }
99
- async getFilterQuery(query, filter, _user) {
100
- for (const [key, value] of Object.entries(filter)){
101
- if (key === 'isRead' && typeof value === 'boolean') {
102
- query.andWhere(`${this.entityName}.isRead = :isRead`, {
103
- isRead: value
104
- });
105
- } else if (key === 'type' && value) {
106
- query.andWhere(`${this.entityName}.type = :type`, {
107
- type: value
108
- });
109
- } else if (key === 'userId' && value) {
110
- query.andWhere(`${this.entityName}.userId = :userId`, {
111
- userId: value
112
- });
113
- }
114
- }
115
- return {
116
- query,
117
- isRaw: false
118
- };
119
- }
120
- async getExtraManipulateQuery(query, filterDto, user) {
121
- const result = await super.getExtraManipulateQuery(query, filterDto, user);
122
- if (user?.id) {
123
- query.andWhere(`${this.entityName}.userId = :currentUserId`, {
124
- currentUserId: user.id
125
- });
126
- }
127
- (0, _utils.applyCompanyFilter)(query, {
128
- isCompanyFeatureEnabled: this.notificationConfig.isCompanyFeatureEnabled(),
129
- entityAlias: this.entityName
130
- }, user);
131
- const filterSort = filterDto?.sort;
132
- if (!filterSort || Object.keys(filterSort).length === 0) {
133
- query.orderBy(`${this.entityName}.createdAt`, 'DESC');
134
- }
135
- return result;
136
- }
137
- async afterInsertOperation(entities, _dto, _user, _qr) {
138
- for (const entity of entities){
139
- const ext = entity;
140
- this.emitToUser(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
141
- }
142
- }
143
- async markAsRead(id, user) {
144
- await this.ensureDataSourceRepository();
145
- const notification = await this.repository.findOne({
146
- where: {
147
- id,
148
- userId: user.id
149
- }
150
- });
151
- if (!notification) {
152
- throw new _common.NotFoundException({
153
- message: 'Notification not found',
154
- messageKey: _config.NOTIFICATION_MESSAGES.NOT_FOUND
155
- });
156
- }
157
- notification.isRead = true;
158
- notification.readAt = new Date();
159
- await this.repository.save(notification);
160
- await Promise.all([
161
- this.clearCacheForAll(),
162
- this.clearCacheForId([
163
- notification
164
- ])
165
- ]);
166
- // Emit to user's sockets in the same company context
167
- const ext = notification;
168
- this.emitToUser(user.id, ext.companyId ?? user.companyId, 'notification:read', {
169
- id
170
- });
171
- await this.publishDomainAction(_config.NOTIFICATION_EVENT_ACTIONS.READ, {
172
- ids: [
173
- notification.id
174
- ],
175
- user
176
- });
177
- return notification;
178
- }
179
- async markAllAsRead(user) {
180
- await this.ensureDataSourceRepository();
181
- const where = {
182
- userId: user.id,
183
- isRead: false
184
- };
185
- if (this.notificationConfig.isCompanyFeatureEnabled() && user.companyId) {
186
- where.companyId = user.companyId;
187
- }
188
- const result = await this.repository.update(where, {
189
- isRead: true,
190
- readAt: new Date()
191
- });
192
- await this.clearCacheForAll();
193
- // Emit to user's sockets in the current company context
194
- this.emitToUser(user.id, user.companyId, 'notification:read-all', {});
195
- await this.publishDomainAction(_config.NOTIFICATION_EVENT_ACTIONS.ALL_READ, {
196
- metadata: {
197
- count: result.affected ?? 0
198
- },
199
- user
200
- });
201
- return result.affected ?? 0;
202
- }
203
- async getUnreadCount(user) {
204
- await this.ensureDataSourceRepository();
205
- const where = {
206
- userId: user.id,
207
- isRead: false
208
- };
209
- if (this.notificationConfig.isCompanyFeatureEnabled() && user.companyId) {
210
- where.companyId = user.companyId;
211
- }
212
- return this.repository.count({
213
- where
214
- });
215
- }
216
- toPayload(entity) {
217
- return {
218
- id: entity.id,
219
- type: entity.type,
220
- title: entity.title,
221
- message: entity.message,
222
- data: entity.data,
223
- createdAt: entity.createdAt
224
- };
225
- }
226
- emitToUser(userId, companyId, event, payload) {
227
- if (!this.gateway) {
228
- return;
229
- }
230
- if (this.notificationConfig.isCompanyFeatureEnabled() && companyId) {
231
- this.gateway.emitToUserInCompany(userId, companyId, event, payload);
232
- } else {
233
- this.gateway.emitToUser(userId, event, payload);
234
- }
235
- }
236
- constructor(cacheManager, utilsService, notificationConfig, dataSourceProvider, gateway){
237
- super(_config.NOTIFICATION_EVENT_ENTITIES.NOTIFICATION, cacheManager, utilsService, NotificationService.name, false, _config.NOTIFICATION_EVENT_MODULE, dataSourceProvider, notificationConfig.isCompanyFeatureEnabled() ? _entities.NotificationWithCompany : _entities.Notification), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "notificationConfig", void 0), _define_property(this, "gateway", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.notificationConfig = notificationConfig, this.gateway = gateway;
238
- }
239
- };
240
- _ts_decorate([
241
- (0, _nestjsshared.LogAction)({
242
- action: 'notification.markAsRead',
243
- module: 'notification'
244
- }),
245
- _ts_metadata("design:type", Function),
246
- _ts_metadata("design:paramtypes", [
247
- String,
248
- typeof _interfaces.ILoggedUserInfo === "undefined" ? Object : _interfaces.ILoggedUserInfo
249
- ]),
250
- _ts_metadata("design:returntype", Promise)
251
- ], NotificationService.prototype, "markAsRead", null);
252
- _ts_decorate([
253
- (0, _nestjsshared.LogAction)({
254
- action: 'notification.markAllAsRead',
255
- module: 'notification'
256
- }),
257
- _ts_metadata("design:type", Function),
258
- _ts_metadata("design:paramtypes", [
259
- typeof _interfaces.ILoggedUserInfo === "undefined" ? Object : _interfaces.ILoggedUserInfo
260
- ]),
261
- _ts_metadata("design:returntype", Promise)
262
- ], NotificationService.prototype, "markAllAsRead", null);
263
- NotificationService = _ts_decorate([
264
- (0, _common.Injectable)({
265
- scope: _common.Scope.REQUEST
266
- }),
267
- _ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
268
- _ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
269
- _ts_param(2, (0, _common.Inject)(_notificationconfigservice.NotificationConfigService)),
270
- _ts_param(3, (0, _common.Inject)(_notificationdatasourceprovider.NotificationDataSourceProvider)),
271
- _ts_param(4, (0, _common.Optional)()),
272
- _ts_param(4, (0, _common.Inject)(_gateways.NotificationGateway)),
273
- _ts_metadata("design:type", Function),
274
- _ts_metadata("design:paramtypes", [
275
- typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
276
- typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
277
- typeof _notificationconfigservice.NotificationConfigService === "undefined" ? Object : _notificationconfigservice.NotificationConfigService,
278
- typeof _notificationdatasourceprovider.NotificationDataSourceProvider === "undefined" ? Object : _notificationdatasourceprovider.NotificationDataSourceProvider,
279
- typeof _gateways.NotificationGateway === "undefined" ? Object : _gateways.NotificationGateway
280
- ])
281
- ], NotificationService);