@flusys/nestjs-notification 5.1.2 → 5.2.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.
@@ -1,10 +1,9 @@
1
- import { INotificationAdapter, NotificationSendOptions, NotificationBulkSendOptions, NotificationType } from '@flusys/nestjs-shared';
1
+ import { INotificationAdapter, INotificationBulkSendOptions, INotificationSendOptions } from '@flusys/nestjs-shared';
2
2
  import { NotificationHelperService } from '../services/notification-helper.service';
3
3
  export declare class NotificationAdapter implements INotificationAdapter {
4
4
  private readonly notificationHelper;
5
5
  constructor(notificationHelper: NotificationHelperService);
6
- send(options: NotificationSendOptions): Promise<void>;
7
- sendToMany(options: NotificationBulkSendOptions): Promise<void>;
8
- broadcastToCompany(companyId: string, title: string, message?: string, type?: NotificationType, data?: Record<string, unknown>): Promise<void>;
6
+ send(options: INotificationSendOptions): Promise<void>;
7
+ sendToMany(options: INotificationBulkSendOptions): Promise<void>;
9
8
  isUserOnline(userId: string): boolean;
10
9
  }
@@ -39,27 +39,10 @@ function _ts_param(paramIndex, decorator) {
39
39
  }
40
40
  let NotificationAdapter = class NotificationAdapter {
41
41
  async send(options) {
42
- await this.notificationHelper.send({
43
- userId: options.userId,
44
- title: options.title,
45
- message: options.message,
46
- type: options.type,
47
- data: options.data,
48
- companyId: options.companyId
49
- });
42
+ await this.notificationHelper.send(options);
50
43
  }
51
44
  async sendToMany(options) {
52
- await this.notificationHelper.sendToMany({
53
- userIds: options.userIds,
54
- title: options.title,
55
- message: options.message,
56
- type: options.type,
57
- data: options.data,
58
- companyId: options.companyId
59
- });
60
- }
61
- async broadcastToCompany(companyId, title, message, type, data) {
62
- await this.notificationHelper.sendToCompany(companyId, title, message, type, data);
45
+ await this.notificationHelper.sendToMany(options);
63
46
  }
64
47
  isUserOnline(userId) {
65
48
  return this.notificationHelper.isUserOnline(userId);
@@ -37,10 +37,6 @@ const ADAPTER_PROVIDER = {
37
37
  };
38
38
  let NotificationModule = class NotificationModule {
39
39
  static forRoot(options) {
40
- const enableRealtime = options.config?.enableRealtime !== false;
41
- const gatewayProviders = enableRealtime ? [
42
- _gateways.NotificationGateway
43
- ] : [];
44
40
  return {
45
41
  module: NotificationModule,
46
42
  global: options.global ?? false,
@@ -51,13 +47,13 @@ let NotificationModule = class NotificationModule {
51
47
  controllers: options.includeController !== false ? CONTROLLERS : [],
52
48
  providers: [
53
49
  ...this.buildProviders(options),
54
- ...gatewayProviders,
50
+ _gateways.NotificationGateway,
55
51
  _adapters.NotificationAdapter,
56
52
  ADAPTER_PROVIDER
57
53
  ],
58
54
  exports: [
59
55
  ...EXPORTED_SERVICES,
60
- ...gatewayProviders,
56
+ _gateways.NotificationGateway,
61
57
  _interfaces.NOTIFICATION_ADAPTER
62
58
  ]
63
59
  };
@@ -48,9 +48,6 @@ let NotificationConfigService = class NotificationConfigService {
48
48
  isMultiTenant() {
49
49
  return this.getDatabaseMode() === 'multi-tenant';
50
50
  }
51
- isRealtimeEnabled() {
52
- return this.options.config?.enableRealtime !== false;
53
- }
54
51
  getJwtSecret() {
55
52
  return this.options.config?.jwtSecret;
56
53
  }
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "NotificationDataSourceProvider", {
9
9
  }
10
10
  });
11
11
  const _modules = require("@flusys/nestjs-shared/modules");
12
- const _constants = require("@flusys/nestjs-shared/constants");
13
12
  const _common = require("@nestjs/common");
14
13
  const _core = require("@nestjs/core");
15
14
  const _express = require("express");
@@ -109,50 +108,6 @@ let NotificationDataSourceProvider = class NotificationDataSourceProvider extend
109
108
  const entities = await this.getNotificationEntities(enableCompanyFeature);
110
109
  return super.createDataSourceFromConfig(config, entities);
111
110
  }
112
- async getSingleDataSource() {
113
- if (NotificationDataSourceProvider.singleDataSource?.isInitialized) {
114
- return NotificationDataSourceProvider.singleDataSource;
115
- }
116
- if (NotificationDataSourceProvider.singleConnectionLock) {
117
- return NotificationDataSourceProvider.singleConnectionLock;
118
- }
119
- const config = this.getDefaultDatabaseConfig();
120
- if (!config) {
121
- throw new _common.InternalServerErrorException({
122
- message: 'No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.',
123
- messageKey: _constants.SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
124
- });
125
- }
126
- const connectionPromise = this.createDataSourceFromConfig(config);
127
- NotificationDataSourceProvider.singleConnectionLock = connectionPromise;
128
- try {
129
- const dataSource = await connectionPromise;
130
- NotificationDataSourceProvider.singleDataSource = dataSource;
131
- return dataSource;
132
- } finally{
133
- NotificationDataSourceProvider.singleConnectionLock = null;
134
- }
135
- }
136
- async getOrCreateTenantConnection(tenant) {
137
- const existing = NotificationDataSourceProvider.tenantConnections.get(tenant.id);
138
- if (existing?.isInitialized) {
139
- return existing;
140
- }
141
- const pendingConnection = NotificationDataSourceProvider.connectionLocks.get(tenant.id);
142
- if (pendingConnection) {
143
- return pendingConnection;
144
- }
145
- const config = this.buildTenantDatabaseConfig(tenant);
146
- const connectionPromise = this.createDataSourceFromConfig(config);
147
- NotificationDataSourceProvider.connectionLocks.set(tenant.id, connectionPromise);
148
- try {
149
- const dataSource = await connectionPromise;
150
- NotificationDataSourceProvider.tenantConnections.set(tenant.id, dataSource);
151
- return dataSource;
152
- } finally{
153
- NotificationDataSourceProvider.connectionLocks.delete(tenant.id);
154
- }
155
- }
156
111
  constructor(configService, request){
157
112
  super(NotificationDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
158
113
  }
@@ -8,15 +8,15 @@ Object.defineProperty(exports, "NotificationHelperService", {
8
8
  return NotificationHelperService;
9
9
  }
10
10
  });
11
- const _common = require("@nestjs/common");
12
- const _classes = require("@flusys/nestjs-shared/classes");
13
11
  const _nestjsshared = require("@flusys/nestjs-shared");
12
+ const _classes = require("@flusys/nestjs-shared/classes");
13
+ const _enums = require("@flusys/nestjs-shared/enums");
14
14
  const _modules = require("@flusys/nestjs-shared/modules");
15
+ const _common = require("@nestjs/common");
16
+ const _entities = require("../entities");
17
+ const _gateways = require("../gateways");
15
18
  const _notificationconfigservice = require("./notification-config.service");
16
19
  const _notificationdatasourceprovider = require("./notification-datasource.provider");
17
- const _gateways = require("../gateways");
18
- const _entities = require("../entities");
19
- const _enums = require("@flusys/nestjs-shared/enums");
20
20
  function _define_property(obj, key, value) {
21
21
  if (key in obj) {
22
22
  Object.defineProperty(obj, key, {
@@ -45,90 +45,68 @@ function _ts_param(paramIndex, decorator) {
45
45
  };
46
46
  }
47
47
  let NotificationHelperService = class NotificationHelperService {
48
- async getDataSource() {
49
- if (!this.dataSource) {
50
- this.dataSource = await this.dataSourceProvider.getDataSource();
51
- }
52
- return this.dataSource;
53
- }
54
- async getRepository() {
55
- const ds = await this.getDataSource();
56
- const EntityClass = this.configService.isCompanyFeatureEnabled() ? _entities.NotificationWithCompany : _entities.Notification;
57
- return ds.getRepository(EntityClass);
58
- }
59
48
  async send(options) {
60
- const { userId, title, message = null, type = _enums.NotificationType.INFO, data = null, companyId } = options;
61
49
  const repo = await this.getRepository();
62
- const entity = {
63
- userId,
64
- type,
65
- title,
66
- message,
67
- data,
68
- isRead: false
69
- };
70
- if (this.configService.isCompanyFeatureEnabled() && companyId) {
71
- entity.companyId = companyId;
72
- }
50
+ const entity = this.buildEntity(options.userId, options);
73
51
  const saved = await repo.save(entity);
74
52
  await this.clearCache();
75
- this.emitRealtime(saved);
53
+ this.emitToUser(saved, options.realtime !== false);
76
54
  return saved;
77
55
  }
78
56
  async sendToMany(options) {
79
- const { userIds, title, message = null, type = _enums.NotificationType.INFO, data = null, companyId } = options;
80
57
  const repo = await this.getRepository();
81
- const entities = userIds.map((userId)=>({
82
- userId,
83
- type,
84
- title,
85
- message,
86
- data,
87
- isRead: false,
88
- ...this.configService.isCompanyFeatureEnabled() && companyId ? {
89
- companyId
90
- } : {}
91
- }));
58
+ const entities = options.userIds.map((userId)=>this.buildEntity(userId, options));
92
59
  const saved = await repo.save(entities);
93
60
  await this.clearCache();
94
- for (const notification of saved){
95
- this.emitRealtime(notification);
61
+ if (options.realtime !== false) {
62
+ setImmediate(()=>{
63
+ for (const notification of saved){
64
+ this.emitToUser(notification, true);
65
+ }
66
+ });
96
67
  }
97
68
  return saved;
98
69
  }
99
- async sendToCompany(companyId, title, message, type = _enums.NotificationType.INFO, data) {
100
- if (!this.configService.isCompanyFeatureEnabled()) {
101
- return;
102
- }
103
- if (this.configService.isRealtimeEnabled() && this.gateway) {
104
- const payload = {
105
- id: `broadcast-${Date.now()}`,
106
- type,
107
- title,
108
- message: message ?? null,
109
- data: data ?? null,
110
- createdAt: new Date()
111
- };
112
- this.gateway.emitToCompany(companyId, 'notification:new', payload);
113
- }
114
- }
115
70
  isUserOnline(userId) {
116
71
  return this.gateway?.isUserOnline(userId) ?? false;
117
72
  }
118
73
  getOnlineUserCount() {
119
74
  return this.gateway?.getOnlineUserCount() ?? 0;
120
75
  }
121
- emitRealtime(notification) {
122
- if (!this.configService.isRealtimeEnabled() || !this.gateway) {
76
+ async getDataSource() {
77
+ if (!this.dataSource) {
78
+ this.dataSource = await this.dataSourceProvider.getDataSource();
79
+ }
80
+ return this.dataSource;
81
+ }
82
+ async getRepository() {
83
+ const ds = await this.getDataSource();
84
+ const EntityClass = this.configService.isCompanyFeatureEnabled() ? _entities.NotificationWithCompany : _entities.Notification;
85
+ return ds.getRepository(EntityClass);
86
+ }
87
+ buildEntity(userId, content) {
88
+ const entity = {
89
+ userId,
90
+ type: content.type ?? _enums.NotificationType.INFO,
91
+ title: content.title,
92
+ message: content.message ?? null,
93
+ data: content.data ?? null,
94
+ isRead: false
95
+ };
96
+ if (this.configService.isCompanyFeatureEnabled() && content.companyId) {
97
+ entity.companyId = content.companyId;
98
+ }
99
+ return entity;
100
+ }
101
+ emitToUser(notification, realtime) {
102
+ if (!realtime || !this.gateway) {
123
103
  return;
124
104
  }
125
105
  const ext = notification;
126
106
  const payload = this.toPayload(notification);
127
107
  if (this.configService.isCompanyFeatureEnabled() && ext.companyId) {
128
- // Company feature enabled - emit only to sockets in matching company context
129
108
  this.gateway.emitToUserInCompany(notification.userId, ext.companyId, 'notification:new', payload);
130
109
  } else {
131
- // No company feature or no companyId - emit to all user's sockets
132
110
  this.gateway.emitToUser(notification.userId, 'notification:new', payload);
133
111
  }
134
112
  }
@@ -143,7 +121,7 @@ let NotificationHelperService = class NotificationHelperService {
143
121
  };
144
122
  }
145
123
  async clearCache() {
146
- await this.utilsService.clearCache(this.entityName, this.cacheManager);
124
+ await this.utilsService.clearCache('notification', this.cacheManager);
147
125
  }
148
126
  constructor(cacheManager, utilsService, configService, dataSourceProvider, gateway){
149
127
  _define_property(this, "cacheManager", void 0);
@@ -151,14 +129,12 @@ let NotificationHelperService = class NotificationHelperService {
151
129
  _define_property(this, "configService", void 0);
152
130
  _define_property(this, "dataSourceProvider", void 0);
153
131
  _define_property(this, "gateway", void 0);
154
- _define_property(this, "entityName", void 0);
155
132
  _define_property(this, "dataSource", void 0);
156
133
  this.cacheManager = cacheManager;
157
134
  this.utilsService = utilsService;
158
135
  this.configService = configService;
159
136
  this.dataSourceProvider = dataSourceProvider;
160
137
  this.gateway = gateway;
161
- this.entityName = 'notification';
162
138
  this.dataSource = null;
163
139
  }
164
140
  };
@@ -169,7 +145,7 @@ _ts_decorate([
169
145
  }),
170
146
  _ts_metadata("design:type", Function),
171
147
  _ts_metadata("design:paramtypes", [
172
- typeof SendNotificationOptions === "undefined" ? Object : SendNotificationOptions
148
+ typeof _nestjsshared.INotificationSendOptions === "undefined" ? Object : _nestjsshared.INotificationSendOptions
173
149
  ]),
174
150
  _ts_metadata("design:returntype", Promise)
175
151
  ], NotificationHelperService.prototype, "send", null);
@@ -180,25 +156,10 @@ _ts_decorate([
180
156
  }),
181
157
  _ts_metadata("design:type", Function),
182
158
  _ts_metadata("design:paramtypes", [
183
- typeof SendBulkNotificationOptions === "undefined" ? Object : SendBulkNotificationOptions
159
+ typeof _nestjsshared.INotificationBulkSendOptions === "undefined" ? Object : _nestjsshared.INotificationBulkSendOptions
184
160
  ]),
185
161
  _ts_metadata("design:returntype", Promise)
186
162
  ], NotificationHelperService.prototype, "sendToMany", null);
187
- _ts_decorate([
188
- (0, _nestjsshared.LogAction)({
189
- action: 'notification.sendToCompany',
190
- module: 'notification'
191
- }),
192
- _ts_metadata("design:type", Function),
193
- _ts_metadata("design:paramtypes", [
194
- String,
195
- String,
196
- Object,
197
- Object,
198
- Object
199
- ]),
200
- _ts_metadata("design:returntype", Promise)
201
- ], NotificationHelperService.prototype, "sendToCompany", null);
202
163
  NotificationHelperService = _ts_decorate([
203
164
  (0, _common.Injectable)(),
204
165
  _ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
@@ -46,13 +46,10 @@ function _ts_param(paramIndex, decorator) {
46
46
  decorator(target, key, paramIndex);
47
47
  };
48
48
  }
49
- let NotificationService = class NotificationService extends _classes.RequestScopedApiService {
49
+ let NotificationService = class NotificationService extends _classes.ApiService {
50
50
  resolveEntity() {
51
51
  return this.notificationConfig.isCompanyFeatureEnabled() ? _entities.NotificationWithCompany : _entities.Notification;
52
52
  }
53
- getDataSourceProvider() {
54
- return this.dataSourceProvider;
55
- }
56
53
  async convertSingleDtoToEntity(dto, user) {
57
54
  let entity = {};
58
55
  if ('id' in dto && dto.id) {
@@ -84,6 +81,24 @@ let NotificationService = class NotificationService extends _classes.RequestScop
84
81
  }
85
82
  return merged;
86
83
  }
84
+ async getSelectQuery(query, _user, select) {
85
+ const fields = select && select.length ? select : [];
86
+ const always = [
87
+ 'createdAt',
88
+ 'updatedAt'
89
+ ];
90
+ const merged = [
91
+ ...new Set([
92
+ ...fields,
93
+ ...always
94
+ ])
95
+ ];
96
+ query.addSelect(merged.map((f)=>`${this.entityName}.${f}`));
97
+ return {
98
+ query,
99
+ isRaw: false
100
+ };
101
+ }
87
102
  async getFilterQuery(query, filter, _user) {
88
103
  for (const [key, value] of Object.entries(filter)){
89
104
  if (key === 'isRead' && typeof value === 'boolean') {
@@ -125,11 +140,11 @@ let NotificationService = class NotificationService extends _classes.RequestScop
125
140
  async afterInsertOperation(entities, _user, _qr) {
126
141
  for (const entity of entities){
127
142
  const ext = entity;
128
- this.emitToUserInCompanyIfRealtime(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
143
+ this.emitToUser(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
129
144
  }
130
145
  }
131
146
  async markAsRead(id, user) {
132
- await this.ensureRepositoryInitialized();
147
+ await this.ensureDataSourceRepository();
133
148
  const notification = await this.repository.findOne({
134
149
  where: {
135
150
  id,
@@ -153,13 +168,13 @@ let NotificationService = class NotificationService extends _classes.RequestScop
153
168
  ]);
154
169
  // Emit to user's sockets in the same company context
155
170
  const ext = notification;
156
- this.emitToUserInCompanyIfRealtime(user.id, ext.companyId ?? user.companyId, 'notification:read', {
171
+ this.emitToUser(user.id, ext.companyId ?? user.companyId, 'notification:read', {
157
172
  id
158
173
  });
159
174
  return notification;
160
175
  }
161
176
  async markAllAsRead(user) {
162
- await this.ensureRepositoryInitialized();
177
+ await this.ensureDataSourceRepository();
163
178
  const where = {
164
179
  userId: user.id,
165
180
  isRead: false
@@ -173,11 +188,11 @@ let NotificationService = class NotificationService extends _classes.RequestScop
173
188
  });
174
189
  await this.clearCacheForAll();
175
190
  // Emit to user's sockets in the current company context
176
- this.emitToUserInCompanyIfRealtime(user.id, user.companyId, 'notification:read-all', {});
191
+ this.emitToUser(user.id, user.companyId, 'notification:read-all', {});
177
192
  return result.affected ?? 0;
178
193
  }
179
194
  async getUnreadCount(user) {
180
- await this.ensureRepositoryInitialized();
195
+ await this.ensureDataSourceRepository();
181
196
  const where = {
182
197
  userId: user.id,
183
198
  isRead: false
@@ -199,24 +214,18 @@ let NotificationService = class NotificationService extends _classes.RequestScop
199
214
  createdAt: entity.createdAt
200
215
  };
201
216
  }
202
- /**
203
- * Emit to user's sockets within a specific company context.
204
- * If company feature is enabled and companyId is provided, only sockets
205
- * connected with that company will receive the event.
206
- */ emitToUserInCompanyIfRealtime(userId, companyId, event, payload) {
207
- if (!this.notificationConfig.isRealtimeEnabled() || !this.gateway) {
217
+ emitToUser(userId, companyId, event, payload) {
218
+ if (!this.gateway) {
208
219
  return;
209
220
  }
210
221
  if (this.notificationConfig.isCompanyFeatureEnabled() && companyId) {
211
- // Company feature enabled - emit only to sockets in matching company context
212
222
  this.gateway.emitToUserInCompany(userId, companyId, event, payload);
213
223
  } else {
214
- // No company feature or no companyId - emit to all user's sockets
215
224
  this.gateway.emitToUser(userId, event, payload);
216
225
  }
217
226
  }
218
227
  constructor(cacheManager, utilsService, notificationConfig, dataSourceProvider, gateway){
219
- super('notification', null, cacheManager, utilsService, NotificationService.name, false, 'notification'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "notificationConfig", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "gateway", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.notificationConfig = notificationConfig, this.dataSourceProvider = dataSourceProvider, this.gateway = gateway;
228
+ super('notification', cacheManager, utilsService, NotificationService.name, false, 'notification', undefined, dataSourceProvider), _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;
220
229
  }
221
230
  };
222
231
  _ts_decorate([
@@ -4,19 +4,19 @@ import { CreateNotificationDto, MarkReadDto, NotificationResponseDto, SendBulkNo
4
4
  import { NotificationHelperService } from '../services/notification-helper.service';
5
5
  import { NotificationService } from '../services/notification.service';
6
6
  declare const NotificationController_base: abstract new (service: NotificationService) => {
7
- readonly enabledEndpoints: import("@flusys/nestjs-shared/classes").ApiEndpoint[] | "all";
7
+ readonly enabledEndpoints: import("@flusys/nestjs-shared").ApiEndpoint[] | "all";
8
8
  service: NotificationService;
9
- isEnabled(endpoint: import("@flusys/nestjs-shared/classes").ApiEndpoint): boolean;
9
+ isEnabled(endpoint: import("@flusys/nestjs-shared").ApiEndpoint): boolean;
10
10
  insert(addDto: CreateNotificationDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<NotificationResponseDto>>;
11
11
  insertMany(addDto: CreateNotificationDto[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<NotificationResponseDto>>;
12
- getById(id: string, body: import("@flusys/nestjs-shared/dtos").GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<NotificationResponseDto>>;
13
- getByIds(body: import("@flusys/nestjs-shared/dtos").GetByIdsDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").ListResponseDto<NotificationResponseDto>>;
12
+ getById(id: string, body: import("@flusys/nestjs-shared").GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<NotificationResponseDto>>;
13
+ getByIds(body: import("@flusys/nestjs-shared").GetByIdsDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").ListResponseDto<NotificationResponseDto>>;
14
14
  update(updateDto: UpdateNotificationDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<NotificationResponseDto>>;
15
15
  updateMany(updateDtos: UpdateNotificationDto[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<NotificationResponseDto>>;
16
16
  bulkUpsert(dtos: (CreateNotificationDto | UpdateNotificationDto)[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<NotificationResponseDto>>;
17
17
  getByFilter(filter: Record<string, any>, user: ILoggedUserInfo | null): Promise<SingleResponseDto<NotificationResponseDto>>;
18
- getAll(filterAndPaginationDto: import("@flusys/nestjs-shared/dtos").FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<import("@flusys/nestjs-shared/dtos").ListResponseDto<NotificationResponseDto>>;
19
- delete(deleteDto: import("@flusys/nestjs-shared/dtos").DeleteDto, user: ILoggedUserInfo | null): Promise<MessageResponseDto>;
18
+ getAll(filterAndPaginationDto: import("@flusys/nestjs-shared").FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<import("@flusys/nestjs-shared").ListResponseDto<NotificationResponseDto>>;
19
+ delete(deleteDto: import("@flusys/nestjs-shared").DeleteDto, user: ILoggedUserInfo | null): Promise<MessageResponseDto>;
20
20
  };
21
21
  export declare class NotificationController extends NotificationController_base {
22
22
  service: NotificationService;
@@ -25,31 +25,14 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { Injectable, Inject } from '@nestjs/common';
28
+ import { Inject, Injectable } from '@nestjs/common';
29
29
  import { NotificationHelperService } from '../services/notification-helper.service';
30
30
  export class NotificationAdapter {
31
31
  async send(options) {
32
- await this.notificationHelper.send({
33
- userId: options.userId,
34
- title: options.title,
35
- message: options.message,
36
- type: options.type,
37
- data: options.data,
38
- companyId: options.companyId
39
- });
32
+ await this.notificationHelper.send(options);
40
33
  }
41
34
  async sendToMany(options) {
42
- await this.notificationHelper.sendToMany({
43
- userIds: options.userIds,
44
- title: options.title,
45
- message: options.message,
46
- type: options.type,
47
- data: options.data,
48
- companyId: options.companyId
49
- });
50
- }
51
- async broadcastToCompany(companyId, title, message, type, data) {
52
- await this.notificationHelper.sendToCompany(companyId, title, message, type, data);
35
+ await this.notificationHelper.sendToMany(options);
53
36
  }
54
37
  isUserOnline(userId) {
55
38
  return this.notificationHelper.isUserOnline(userId);
@@ -27,10 +27,6 @@ const ADAPTER_PROVIDER = {
27
27
  };
28
28
  export class NotificationModule {
29
29
  static forRoot(options) {
30
- const enableRealtime = options.config?.enableRealtime !== false;
31
- const gatewayProviders = enableRealtime ? [
32
- NotificationGateway
33
- ] : [];
34
30
  return {
35
31
  module: NotificationModule,
36
32
  global: options.global ?? false,
@@ -41,13 +37,13 @@ export class NotificationModule {
41
37
  controllers: options.includeController !== false ? CONTROLLERS : [],
42
38
  providers: [
43
39
  ...this.buildProviders(options),
44
- ...gatewayProviders,
40
+ NotificationGateway,
45
41
  NotificationAdapter,
46
42
  ADAPTER_PROVIDER
47
43
  ],
48
44
  exports: [
49
45
  ...EXPORTED_SERVICES,
50
- ...gatewayProviders,
46
+ NotificationGateway,
51
47
  NOTIFICATION_ADAPTER
52
48
  ]
53
49
  };
@@ -38,9 +38,6 @@ export class NotificationConfigService {
38
38
  isMultiTenant() {
39
39
  return this.getDatabaseMode() === 'multi-tenant';
40
40
  }
41
- isRealtimeEnabled() {
42
- return this.options.config?.enableRealtime !== false;
43
- }
44
41
  getJwtSecret() {
45
42
  return this.options.config?.jwtSecret;
46
43
  }
@@ -26,8 +26,7 @@ function _ts_param(paramIndex, decorator) {
26
26
  };
27
27
  }
28
28
  import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
29
- import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
30
- import { Inject, Injectable, InternalServerErrorException, Optional, Scope } from '@nestjs/common';
29
+ import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
31
30
  import { REQUEST } from '@nestjs/core';
32
31
  import { Request } from 'express';
33
32
  import { NotificationConfigService } from './notification-config.service';
@@ -58,50 +57,6 @@ export class NotificationDataSourceProvider extends MultiTenantDataSourceService
58
57
  const entities = await this.getNotificationEntities(enableCompanyFeature);
59
58
  return super.createDataSourceFromConfig(config, entities);
60
59
  }
61
- async getSingleDataSource() {
62
- if (NotificationDataSourceProvider.singleDataSource?.isInitialized) {
63
- return NotificationDataSourceProvider.singleDataSource;
64
- }
65
- if (NotificationDataSourceProvider.singleConnectionLock) {
66
- return NotificationDataSourceProvider.singleConnectionLock;
67
- }
68
- const config = this.getDefaultDatabaseConfig();
69
- if (!config) {
70
- throw new InternalServerErrorException({
71
- message: 'No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.',
72
- messageKey: SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
73
- });
74
- }
75
- const connectionPromise = this.createDataSourceFromConfig(config);
76
- NotificationDataSourceProvider.singleConnectionLock = connectionPromise;
77
- try {
78
- const dataSource = await connectionPromise;
79
- NotificationDataSourceProvider.singleDataSource = dataSource;
80
- return dataSource;
81
- } finally{
82
- NotificationDataSourceProvider.singleConnectionLock = null;
83
- }
84
- }
85
- async getOrCreateTenantConnection(tenant) {
86
- const existing = NotificationDataSourceProvider.tenantConnections.get(tenant.id);
87
- if (existing?.isInitialized) {
88
- return existing;
89
- }
90
- const pendingConnection = NotificationDataSourceProvider.connectionLocks.get(tenant.id);
91
- if (pendingConnection) {
92
- return pendingConnection;
93
- }
94
- const config = this.buildTenantDatabaseConfig(tenant);
95
- const connectionPromise = this.createDataSourceFromConfig(config);
96
- NotificationDataSourceProvider.connectionLocks.set(tenant.id, connectionPromise);
97
- try {
98
- const dataSource = await connectionPromise;
99
- NotificationDataSourceProvider.tenantConnections.set(tenant.id, dataSource);
100
- return dataSource;
101
- } finally{
102
- NotificationDataSourceProvider.connectionLocks.delete(tenant.id);
103
- }
104
- }
105
60
  constructor(configService, request){
106
61
  super(NotificationDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
107
62
  }
@@ -25,100 +25,78 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { Inject, Injectable, Optional } from '@nestjs/common';
28
+ import { INotificationBulkSendOptions, INotificationSendOptions, LogAction } from '@flusys/nestjs-shared';
29
29
  import { HybridCache } from '@flusys/nestjs-shared/classes';
30
- import { LogAction } from '@flusys/nestjs-shared';
30
+ import { NotificationType } from '@flusys/nestjs-shared/enums';
31
31
  import { UtilsService } from '@flusys/nestjs-shared/modules';
32
+ import { Inject, Injectable, Optional } from '@nestjs/common';
33
+ import { Notification, NotificationWithCompany } from '../entities';
34
+ import { NotificationGateway } from '../gateways';
32
35
  import { NotificationConfigService } from './notification-config.service';
33
36
  import { NotificationDataSourceProvider } from './notification-datasource.provider';
34
- import { NotificationGateway } from '../gateways';
35
- import { Notification, NotificationWithCompany } from '../entities';
36
- import { NotificationType } from '@flusys/nestjs-shared/enums';
37
37
  export class NotificationHelperService {
38
- async getDataSource() {
39
- if (!this.dataSource) {
40
- this.dataSource = await this.dataSourceProvider.getDataSource();
41
- }
42
- return this.dataSource;
43
- }
44
- async getRepository() {
45
- const ds = await this.getDataSource();
46
- const EntityClass = this.configService.isCompanyFeatureEnabled() ? NotificationWithCompany : Notification;
47
- return ds.getRepository(EntityClass);
48
- }
49
38
  async send(options) {
50
- const { userId, title, message = null, type = NotificationType.INFO, data = null, companyId } = options;
51
39
  const repo = await this.getRepository();
52
- const entity = {
53
- userId,
54
- type,
55
- title,
56
- message,
57
- data,
58
- isRead: false
59
- };
60
- if (this.configService.isCompanyFeatureEnabled() && companyId) {
61
- entity.companyId = companyId;
62
- }
40
+ const entity = this.buildEntity(options.userId, options);
63
41
  const saved = await repo.save(entity);
64
42
  await this.clearCache();
65
- this.emitRealtime(saved);
43
+ this.emitToUser(saved, options.realtime !== false);
66
44
  return saved;
67
45
  }
68
46
  async sendToMany(options) {
69
- const { userIds, title, message = null, type = NotificationType.INFO, data = null, companyId } = options;
70
47
  const repo = await this.getRepository();
71
- const entities = userIds.map((userId)=>({
72
- userId,
73
- type,
74
- title,
75
- message,
76
- data,
77
- isRead: false,
78
- ...this.configService.isCompanyFeatureEnabled() && companyId ? {
79
- companyId
80
- } : {}
81
- }));
48
+ const entities = options.userIds.map((userId)=>this.buildEntity(userId, options));
82
49
  const saved = await repo.save(entities);
83
50
  await this.clearCache();
84
- for (const notification of saved){
85
- this.emitRealtime(notification);
51
+ if (options.realtime !== false) {
52
+ setImmediate(()=>{
53
+ for (const notification of saved){
54
+ this.emitToUser(notification, true);
55
+ }
56
+ });
86
57
  }
87
58
  return saved;
88
59
  }
89
- async sendToCompany(companyId, title, message, type = NotificationType.INFO, data) {
90
- if (!this.configService.isCompanyFeatureEnabled()) {
91
- return;
92
- }
93
- if (this.configService.isRealtimeEnabled() && this.gateway) {
94
- const payload = {
95
- id: `broadcast-${Date.now()}`,
96
- type,
97
- title,
98
- message: message ?? null,
99
- data: data ?? null,
100
- createdAt: new Date()
101
- };
102
- this.gateway.emitToCompany(companyId, 'notification:new', payload);
103
- }
104
- }
105
60
  isUserOnline(userId) {
106
61
  return this.gateway?.isUserOnline(userId) ?? false;
107
62
  }
108
63
  getOnlineUserCount() {
109
64
  return this.gateway?.getOnlineUserCount() ?? 0;
110
65
  }
111
- emitRealtime(notification) {
112
- if (!this.configService.isRealtimeEnabled() || !this.gateway) {
66
+ async getDataSource() {
67
+ if (!this.dataSource) {
68
+ this.dataSource = await this.dataSourceProvider.getDataSource();
69
+ }
70
+ return this.dataSource;
71
+ }
72
+ async getRepository() {
73
+ const ds = await this.getDataSource();
74
+ const EntityClass = this.configService.isCompanyFeatureEnabled() ? NotificationWithCompany : Notification;
75
+ return ds.getRepository(EntityClass);
76
+ }
77
+ buildEntity(userId, content) {
78
+ const entity = {
79
+ userId,
80
+ type: content.type ?? NotificationType.INFO,
81
+ title: content.title,
82
+ message: content.message ?? null,
83
+ data: content.data ?? null,
84
+ isRead: false
85
+ };
86
+ if (this.configService.isCompanyFeatureEnabled() && content.companyId) {
87
+ entity.companyId = content.companyId;
88
+ }
89
+ return entity;
90
+ }
91
+ emitToUser(notification, realtime) {
92
+ if (!realtime || !this.gateway) {
113
93
  return;
114
94
  }
115
95
  const ext = notification;
116
96
  const payload = this.toPayload(notification);
117
97
  if (this.configService.isCompanyFeatureEnabled() && ext.companyId) {
118
- // Company feature enabled - emit only to sockets in matching company context
119
98
  this.gateway.emitToUserInCompany(notification.userId, ext.companyId, 'notification:new', payload);
120
99
  } else {
121
- // No company feature or no companyId - emit to all user's sockets
122
100
  this.gateway.emitToUser(notification.userId, 'notification:new', payload);
123
101
  }
124
102
  }
@@ -133,7 +111,7 @@ export class NotificationHelperService {
133
111
  };
134
112
  }
135
113
  async clearCache() {
136
- await this.utilsService.clearCache(this.entityName, this.cacheManager);
114
+ await this.utilsService.clearCache('notification', this.cacheManager);
137
115
  }
138
116
  constructor(cacheManager, utilsService, configService, dataSourceProvider, gateway){
139
117
  _define_property(this, "cacheManager", void 0);
@@ -141,14 +119,12 @@ export class NotificationHelperService {
141
119
  _define_property(this, "configService", void 0);
142
120
  _define_property(this, "dataSourceProvider", void 0);
143
121
  _define_property(this, "gateway", void 0);
144
- _define_property(this, "entityName", void 0);
145
122
  _define_property(this, "dataSource", void 0);
146
123
  this.cacheManager = cacheManager;
147
124
  this.utilsService = utilsService;
148
125
  this.configService = configService;
149
126
  this.dataSourceProvider = dataSourceProvider;
150
127
  this.gateway = gateway;
151
- this.entityName = 'notification';
152
128
  this.dataSource = null;
153
129
  }
154
130
  }
@@ -159,7 +135,7 @@ _ts_decorate([
159
135
  }),
160
136
  _ts_metadata("design:type", Function),
161
137
  _ts_metadata("design:paramtypes", [
162
- typeof SendNotificationOptions === "undefined" ? Object : SendNotificationOptions
138
+ typeof INotificationSendOptions === "undefined" ? Object : INotificationSendOptions
163
139
  ]),
164
140
  _ts_metadata("design:returntype", Promise)
165
141
  ], NotificationHelperService.prototype, "send", null);
@@ -170,25 +146,10 @@ _ts_decorate([
170
146
  }),
171
147
  _ts_metadata("design:type", Function),
172
148
  _ts_metadata("design:paramtypes", [
173
- typeof SendBulkNotificationOptions === "undefined" ? Object : SendBulkNotificationOptions
149
+ typeof INotificationBulkSendOptions === "undefined" ? Object : INotificationBulkSendOptions
174
150
  ]),
175
151
  _ts_metadata("design:returntype", Promise)
176
152
  ], NotificationHelperService.prototype, "sendToMany", null);
177
- _ts_decorate([
178
- LogAction({
179
- action: 'notification.sendToCompany',
180
- module: 'notification'
181
- }),
182
- _ts_metadata("design:type", Function),
183
- _ts_metadata("design:paramtypes", [
184
- String,
185
- String,
186
- Object,
187
- Object,
188
- Object
189
- ]),
190
- _ts_metadata("design:returntype", Promise)
191
- ], NotificationHelperService.prototype, "sendToCompany", null);
192
153
  NotificationHelperService = _ts_decorate([
193
154
  Injectable(),
194
155
  _ts_param(0, Inject('CACHE_INSTANCE')),
@@ -26,7 +26,7 @@ function _ts_param(paramIndex, decorator) {
26
26
  };
27
27
  }
28
28
  import { LogAction } from '@flusys/nestjs-shared';
29
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
29
+ import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
30
30
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
31
31
  import { UtilsService } from '@flusys/nestjs-shared/modules';
32
32
  import { applyCompanyFilter } from '@flusys/nestjs-shared/utils';
@@ -36,13 +36,10 @@ import { Notification, NotificationWithCompany } from '../entities';
36
36
  import { NotificationGateway } from '../gateways';
37
37
  import { NotificationConfigService } from './notification-config.service';
38
38
  import { NotificationDataSourceProvider } from './notification-datasource.provider';
39
- export class NotificationService extends RequestScopedApiService {
39
+ export class NotificationService extends ApiService {
40
40
  resolveEntity() {
41
41
  return this.notificationConfig.isCompanyFeatureEnabled() ? NotificationWithCompany : Notification;
42
42
  }
43
- getDataSourceProvider() {
44
- return this.dataSourceProvider;
45
- }
46
43
  async convertSingleDtoToEntity(dto, user) {
47
44
  let entity = {};
48
45
  if ('id' in dto && dto.id) {
@@ -74,6 +71,24 @@ export class NotificationService extends RequestScopedApiService {
74
71
  }
75
72
  return merged;
76
73
  }
74
+ async getSelectQuery(query, _user, select) {
75
+ const fields = select && select.length ? select : [];
76
+ const always = [
77
+ 'createdAt',
78
+ 'updatedAt'
79
+ ];
80
+ const merged = [
81
+ ...new Set([
82
+ ...fields,
83
+ ...always
84
+ ])
85
+ ];
86
+ query.addSelect(merged.map((f)=>`${this.entityName}.${f}`));
87
+ return {
88
+ query,
89
+ isRaw: false
90
+ };
91
+ }
77
92
  async getFilterQuery(query, filter, _user) {
78
93
  for (const [key, value] of Object.entries(filter)){
79
94
  if (key === 'isRead' && typeof value === 'boolean') {
@@ -115,11 +130,11 @@ export class NotificationService extends RequestScopedApiService {
115
130
  async afterInsertOperation(entities, _user, _qr) {
116
131
  for (const entity of entities){
117
132
  const ext = entity;
118
- this.emitToUserInCompanyIfRealtime(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
133
+ this.emitToUser(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
119
134
  }
120
135
  }
121
136
  async markAsRead(id, user) {
122
- await this.ensureRepositoryInitialized();
137
+ await this.ensureDataSourceRepository();
123
138
  const notification = await this.repository.findOne({
124
139
  where: {
125
140
  id,
@@ -143,13 +158,13 @@ export class NotificationService extends RequestScopedApiService {
143
158
  ]);
144
159
  // Emit to user's sockets in the same company context
145
160
  const ext = notification;
146
- this.emitToUserInCompanyIfRealtime(user.id, ext.companyId ?? user.companyId, 'notification:read', {
161
+ this.emitToUser(user.id, ext.companyId ?? user.companyId, 'notification:read', {
147
162
  id
148
163
  });
149
164
  return notification;
150
165
  }
151
166
  async markAllAsRead(user) {
152
- await this.ensureRepositoryInitialized();
167
+ await this.ensureDataSourceRepository();
153
168
  const where = {
154
169
  userId: user.id,
155
170
  isRead: false
@@ -163,11 +178,11 @@ export class NotificationService extends RequestScopedApiService {
163
178
  });
164
179
  await this.clearCacheForAll();
165
180
  // Emit to user's sockets in the current company context
166
- this.emitToUserInCompanyIfRealtime(user.id, user.companyId, 'notification:read-all', {});
181
+ this.emitToUser(user.id, user.companyId, 'notification:read-all', {});
167
182
  return result.affected ?? 0;
168
183
  }
169
184
  async getUnreadCount(user) {
170
- await this.ensureRepositoryInitialized();
185
+ await this.ensureDataSourceRepository();
171
186
  const where = {
172
187
  userId: user.id,
173
188
  isRead: false
@@ -189,24 +204,18 @@ export class NotificationService extends RequestScopedApiService {
189
204
  createdAt: entity.createdAt
190
205
  };
191
206
  }
192
- /**
193
- * Emit to user's sockets within a specific company context.
194
- * If company feature is enabled and companyId is provided, only sockets
195
- * connected with that company will receive the event.
196
- */ emitToUserInCompanyIfRealtime(userId, companyId, event, payload) {
197
- if (!this.notificationConfig.isRealtimeEnabled() || !this.gateway) {
207
+ emitToUser(userId, companyId, event, payload) {
208
+ if (!this.gateway) {
198
209
  return;
199
210
  }
200
211
  if (this.notificationConfig.isCompanyFeatureEnabled() && companyId) {
201
- // Company feature enabled - emit only to sockets in matching company context
202
212
  this.gateway.emitToUserInCompany(userId, companyId, event, payload);
203
213
  } else {
204
- // No company feature or no companyId - emit to all user's sockets
205
214
  this.gateway.emitToUser(userId, event, payload);
206
215
  }
207
216
  }
208
217
  constructor(cacheManager, utilsService, notificationConfig, dataSourceProvider, gateway){
209
- super('notification', null, cacheManager, utilsService, NotificationService.name, false, 'notification'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "notificationConfig", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "gateway", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.notificationConfig = notificationConfig, this.dataSourceProvider = dataSourceProvider, this.gateway = gateway;
218
+ super('notification', cacheManager, utilsService, NotificationService.name, false, 'notification', undefined, dataSourceProvider), _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;
210
219
  }
211
220
  }
212
221
  _ts_decorate([
@@ -1,7 +1,6 @@
1
1
  import { IBootstrapAppConfig, IDataSourceServiceOptions, IDynamicModuleConfig, IModuleOptionsFactory } from '@flusys/nestjs-core';
2
2
  import { ModuleMetadata, Type } from '@nestjs/common';
3
3
  export interface INotificationModuleConfig extends IDataSourceServiceOptions {
4
- enableRealtime?: boolean;
5
4
  jwtSecret?: string;
6
5
  }
7
6
  export interface NotificationModuleOptions extends IDynamicModuleConfig {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-notification",
3
- "version": "5.1.2",
3
+ "version": "5.2.0",
4
4
  "description": "Notification module with real-time Socket.IO support",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -77,23 +77,23 @@
77
77
  }
78
78
  },
79
79
  "peerDependencies": {
80
- "@nestjs/common": "^10.0.0 || ^11.0.0",
81
- "@nestjs/config": "^3.0.0 || ^4.0.0",
82
- "@nestjs/core": "^10.0.0 || ^11.0.0",
83
- "@nestjs/platform-express": "^10.0.0 || ^11.0.0",
84
- "@nestjs/swagger": "^7.0.0 || ^11.0.0",
85
- "@nestjs/typeorm": "^10.0.0 || ^11.0.0",
86
- "@nestjs/websockets": "^10.0.0 || ^11.0.0",
87
- "@nestjs/platform-socket.io": "^10.0.0 || ^11.0.0",
88
- "class-transformer": "^0.5.0",
89
- "class-validator": "^0.14.0",
90
- "socket.io": "^4.0.0",
80
+ "@nestjs/common": "^11.0.0",
81
+ "@nestjs/config": "^4.0.0",
82
+ "@nestjs/core": "^11.0.0",
83
+ "@nestjs/platform-express": "^11.0.0",
84
+ "@nestjs/swagger": "^11.0.0",
85
+ "@nestjs/typeorm": "^11.0.0",
86
+ "@nestjs/websockets": "^11.0.0",
87
+ "@nestjs/platform-socket.io": "^11.0.0",
88
+ "class-transformer": "^0.5.1",
89
+ "class-validator": "^0.14.0 || ^0.15.0",
90
+ "socket.io": "^4.8.0",
91
91
  "typeorm": "^0.3.0",
92
- "express": "^4.18.0"
92
+ "express": "^4.18.0 || ^5.0.0"
93
93
  },
94
94
  "dependencies": {
95
- "@flusys/nestjs-core": "5.1.2",
96
- "@flusys/nestjs-shared": "5.1.2",
95
+ "@flusys/nestjs-core": "5.2.0",
96
+ "@flusys/nestjs-shared": "5.2.0",
97
97
  "jsonwebtoken": "^9.0.0"
98
98
  }
99
99
  }
@@ -7,7 +7,6 @@ export declare class NotificationConfigService implements IModuleConfigService {
7
7
  isCompanyFeatureEnabled(): boolean;
8
8
  getDatabaseMode(): DatabaseMode;
9
9
  isMultiTenant(): boolean;
10
- isRealtimeEnabled(): boolean;
11
10
  getJwtSecret(): string | undefined;
12
11
  getOptions(): NotificationModuleOptions;
13
12
  }
@@ -16,6 +16,4 @@ export declare class NotificationDataSourceProvider extends MultiTenantDataSourc
16
16
  getEnableCompanyFeatureForTenant(tenant?: ITenantDatabaseConfig): boolean;
17
17
  getNotificationEntities(enableCompanyFeature?: boolean): Promise<any[]>;
18
18
  protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
19
- protected getSingleDataSource(): Promise<DataSource>;
20
- protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
21
19
  }
@@ -1,43 +1,26 @@
1
+ import { INotificationBulkSendOptions, INotificationSendOptions } from '@flusys/nestjs-shared';
1
2
  import { HybridCache } from '@flusys/nestjs-shared/classes';
2
3
  import { UtilsService } from '@flusys/nestjs-shared/modules';
4
+ import { NotificationBase } from '../entities';
5
+ import { NotificationGateway } from '../gateways';
3
6
  import { NotificationConfigService } from './notification-config.service';
4
7
  import { NotificationDataSourceProvider } from './notification-datasource.provider';
5
- import { NotificationGateway } from '../gateways';
6
- import { NotificationBase } from '../entities';
7
- import { NotificationType } from '@flusys/nestjs-shared/enums';
8
- export interface SendNotificationOptions {
9
- userId: string;
10
- title: string;
11
- message?: string | null;
12
- type?: NotificationType | string;
13
- data?: Record<string, unknown> | null;
14
- companyId?: string | null;
15
- }
16
- export interface SendBulkNotificationOptions {
17
- userIds: string[];
18
- title: string;
19
- message?: string | null;
20
- type?: NotificationType | string;
21
- data?: Record<string, unknown> | null;
22
- companyId?: string | null;
23
- }
24
8
  export declare class NotificationHelperService {
25
9
  private readonly cacheManager;
26
10
  private readonly utilsService;
27
11
  private readonly configService;
28
12
  private readonly dataSourceProvider;
29
13
  private readonly gateway?;
30
- private readonly entityName;
31
14
  private dataSource;
32
- constructor(cacheManager: HybridCache, utilsService: UtilsService, configService: NotificationConfigService, dataSourceProvider: NotificationDataSourceProvider, gateway?: NotificationGateway);
33
- private getDataSource;
34
- private getRepository;
35
- send(options: SendNotificationOptions): Promise<NotificationBase>;
36
- sendToMany(options: SendBulkNotificationOptions): Promise<NotificationBase[]>;
37
- sendToCompany(companyId: string, title: string, message?: string | null, type?: NotificationType | string, data?: Record<string, unknown> | null): Promise<void>;
15
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, configService: NotificationConfigService, dataSourceProvider: NotificationDataSourceProvider, gateway?: NotificationGateway | undefined);
16
+ send(options: INotificationSendOptions): Promise<NotificationBase>;
17
+ sendToMany(options: INotificationBulkSendOptions): Promise<NotificationBase[]>;
38
18
  isUserOnline(userId: string): boolean;
39
19
  getOnlineUserCount(): number;
40
- private emitRealtime;
20
+ private getDataSource;
21
+ private getRepository;
22
+ private buildEntity;
23
+ private emitToUser;
41
24
  private toPayload;
42
25
  private clearCache;
43
26
  }
@@ -1,4 +1,4 @@
1
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
1
+ import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
2
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
3
3
  import { UtilsService } from '@flusys/nestjs-shared/modules';
4
4
  import { EntityTarget, QueryRunner, SelectQueryBuilder } from 'typeorm';
@@ -8,16 +8,18 @@ import { NotificationGateway } from '../gateways';
8
8
  import { INotification } from '../interfaces';
9
9
  import { NotificationConfigService } from './notification-config.service';
10
10
  import { NotificationDataSourceProvider } from './notification-datasource.provider';
11
- export declare class NotificationService extends RequestScopedApiService<CreateNotificationDto, UpdateNotificationDto, INotification, NotificationBase> {
11
+ export declare class NotificationService extends ApiService<CreateNotificationDto, UpdateNotificationDto, INotification, NotificationBase> {
12
12
  protected cacheManager: HybridCache;
13
13
  protected utilsService: UtilsService;
14
14
  private readonly notificationConfig;
15
- private readonly dataSourceProvider;
16
15
  private readonly gateway?;
17
- constructor(cacheManager: HybridCache, utilsService: UtilsService, notificationConfig: NotificationConfigService, dataSourceProvider: NotificationDataSourceProvider, gateway?: NotificationGateway);
16
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, notificationConfig: NotificationConfigService, dataSourceProvider: NotificationDataSourceProvider, gateway?: NotificationGateway | undefined);
18
17
  protected resolveEntity(): EntityTarget<NotificationBase>;
19
- protected getDataSourceProvider(): NotificationDataSourceProvider;
20
18
  convertSingleDtoToEntity(dto: CreateNotificationDto | UpdateNotificationDto, user: ILoggedUserInfo | null): Promise<NotificationBase>;
19
+ protected getSelectQuery(query: SelectQueryBuilder<NotificationBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
20
+ query: SelectQueryBuilder<NotificationBase>;
21
+ isRaw: boolean;
22
+ }>;
21
23
  protected getFilterQuery(query: SelectQueryBuilder<NotificationBase>, filter: Record<string, unknown>, _user: ILoggedUserInfo | null): Promise<{
22
24
  query: SelectQueryBuilder<NotificationBase>;
23
25
  isRaw: boolean;
@@ -31,5 +33,5 @@ export declare class NotificationService extends RequestScopedApiService<CreateN
31
33
  markAllAsRead(user: ILoggedUserInfo): Promise<number>;
32
34
  getUnreadCount(user: ILoggedUserInfo): Promise<number>;
33
35
  private toPayload;
34
- private emitToUserInCompanyIfRealtime;
36
+ private emitToUser;
35
37
  }