@flusys/nestjs-notification 5.1.1 → 5.1.3
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.
- package/adapters/notification.adapter.d.ts +3 -4
- package/cjs/adapters/notification.adapter.js +2 -19
- package/cjs/controllers/notification.controller.js +13 -4
- package/cjs/dtos/notification.dto.js +65 -14
- package/cjs/modules/notification.module.js +2 -6
- package/cjs/services/notification-config.service.js +0 -3
- package/cjs/services/notification-datasource.provider.js +0 -45
- package/cjs/services/notification-helper.service.js +44 -83
- package/cjs/services/notification.service.js +10 -19
- package/controllers/notification.controller.d.ts +6 -6
- package/dtos/notification.dto.d.ts +1 -1
- package/fesm/adapters/notification.adapter.js +3 -20
- package/fesm/controllers/notification.controller.js +13 -4
- package/fesm/dtos/notification.dto.js +65 -14
- package/fesm/modules/notification.module.js +2 -6
- package/fesm/services/notification-config.service.js +0 -3
- package/fesm/services/notification-datasource.provider.js +1 -46
- package/fesm/services/notification-helper.service.js +44 -83
- package/fesm/services/notification.service.js +11 -20
- package/interfaces/notification-module.interface.d.ts +0 -1
- package/package.json +15 -15
- package/services/notification-config.service.d.ts +0 -1
- package/services/notification-datasource.provider.d.ts +0 -2
- package/services/notification-helper.service.d.ts +10 -27
- package/services/notification.service.d.ts +4 -6
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { INotificationAdapter,
|
|
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:
|
|
7
|
-
sendToMany(options:
|
|
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);
|
|
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "NotificationController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
12
|
-
const _config = require("../config");
|
|
13
12
|
const _decorators = require("@flusys/nestjs-shared/decorators");
|
|
14
13
|
const _dtos = require("@flusys/nestjs-shared/dtos");
|
|
15
14
|
const _guards = require("@flusys/nestjs-shared/guards");
|
|
@@ -17,6 +16,7 @@ const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
|
17
16
|
const _common = require("@nestjs/common");
|
|
18
17
|
const _swagger = require("@nestjs/swagger");
|
|
19
18
|
const _classtransformer = require("class-transformer");
|
|
19
|
+
const _config = require("../config");
|
|
20
20
|
const _dtos1 = require("../dtos");
|
|
21
21
|
const _notificationhelperservice = require("../services/notification-helper.service");
|
|
22
22
|
const _notificationservice = require("../services/notification.service");
|
|
@@ -93,11 +93,14 @@ let NotificationController = class NotificationController extends (0, _classes.c
|
|
|
93
93
|
}) {
|
|
94
94
|
async markAsRead(dto, user) {
|
|
95
95
|
const notification = await this.service.markAsRead(dto.id, user);
|
|
96
|
+
const plainOptions = {
|
|
97
|
+
excludeExtraneousValues: true
|
|
98
|
+
};
|
|
96
99
|
return {
|
|
97
100
|
success: true,
|
|
98
101
|
message: 'Notification marked as read',
|
|
99
102
|
messageKey: _config.NOTIFICATION_MESSAGES.MARK_READ_SUCCESS,
|
|
100
|
-
data: (0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, notification)
|
|
103
|
+
data: (0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, notification, plainOptions)
|
|
101
104
|
};
|
|
102
105
|
}
|
|
103
106
|
async markAllAsRead(user) {
|
|
@@ -131,11 +134,14 @@ let NotificationController = class NotificationController extends (0, _classes.c
|
|
|
131
134
|
data: dto.data,
|
|
132
135
|
companyId: dto.companyId
|
|
133
136
|
});
|
|
137
|
+
const plainOptions = {
|
|
138
|
+
excludeExtraneousValues: true
|
|
139
|
+
};
|
|
134
140
|
return {
|
|
135
141
|
success: true,
|
|
136
142
|
message: 'Notification sent successfully',
|
|
137
143
|
messageKey: _config.NOTIFICATION_MESSAGES.SEND_SUCCESS,
|
|
138
|
-
data: (0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, notification)
|
|
144
|
+
data: (0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, notification, plainOptions)
|
|
139
145
|
};
|
|
140
146
|
}
|
|
141
147
|
async sendBulkNotification(dto) {
|
|
@@ -147,6 +153,9 @@ let NotificationController = class NotificationController extends (0, _classes.c
|
|
|
147
153
|
data: dto.data,
|
|
148
154
|
companyId: dto.companyId
|
|
149
155
|
});
|
|
156
|
+
const plainOptions = {
|
|
157
|
+
excludeExtraneousValues: true
|
|
158
|
+
};
|
|
150
159
|
return {
|
|
151
160
|
success: true,
|
|
152
161
|
message: `${notifications.length} notifications sent successfully`,
|
|
@@ -154,7 +163,7 @@ let NotificationController = class NotificationController extends (0, _classes.c
|
|
|
154
163
|
messageVariables: {
|
|
155
164
|
count: notifications.length
|
|
156
165
|
},
|
|
157
|
-
data: notifications.map((n)=>(0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, n)),
|
|
166
|
+
data: notifications.map((n)=>(0, _classtransformer.plainToInstance)(_dtos1.NotificationResponseDto, n, plainOptions)),
|
|
158
167
|
meta: {
|
|
159
168
|
count: notifications.length,
|
|
160
169
|
total: dto.userIds.length
|
|
@@ -31,10 +31,10 @@ _export(exports, {
|
|
|
31
31
|
return UpdateNotificationDto;
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
|
+
const _enums = require("@flusys/nestjs-shared/enums");
|
|
34
35
|
const _swagger = require("@nestjs/swagger");
|
|
35
36
|
const _classtransformer = require("class-transformer");
|
|
36
37
|
const _classvalidator = require("class-validator");
|
|
37
|
-
const _enums = require("@flusys/nestjs-shared/enums");
|
|
38
38
|
function _define_property(obj, key, value) {
|
|
39
39
|
if (key in obj) {
|
|
40
40
|
Object.defineProperty(obj, key, {
|
|
@@ -173,59 +173,106 @@ let NotificationResponseDto = class NotificationResponseDto {
|
|
|
173
173
|
};
|
|
174
174
|
_ts_decorate([
|
|
175
175
|
(0, _classtransformer.Expose)(),
|
|
176
|
-
(0, _swagger.ApiProperty)(
|
|
176
|
+
(0, _swagger.ApiProperty)({
|
|
177
|
+
description: 'Unique identifier of the notification',
|
|
178
|
+
example: '018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c'
|
|
179
|
+
}),
|
|
177
180
|
_ts_metadata("design:type", String)
|
|
178
181
|
], NotificationResponseDto.prototype, "id", void 0);
|
|
179
182
|
_ts_decorate([
|
|
180
183
|
(0, _classtransformer.Expose)(),
|
|
181
|
-
(0, _swagger.ApiProperty)(
|
|
184
|
+
(0, _swagger.ApiProperty)({
|
|
185
|
+
description: 'ID of the user this notification belongs to',
|
|
186
|
+
example: '018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c'
|
|
187
|
+
}),
|
|
182
188
|
_ts_metadata("design:type", String)
|
|
183
189
|
], NotificationResponseDto.prototype, "userId", void 0);
|
|
184
190
|
_ts_decorate([
|
|
185
191
|
(0, _classtransformer.Expose)(),
|
|
186
192
|
(0, _swagger.ApiProperty)({
|
|
187
|
-
|
|
193
|
+
description: 'Category of the notification',
|
|
194
|
+
enum: _enums.NotificationType,
|
|
195
|
+
example: _enums.NotificationType.SUCCESS
|
|
188
196
|
}),
|
|
189
|
-
_ts_metadata("design:type",
|
|
197
|
+
_ts_metadata("design:type", typeof _enums.NotificationType === "undefined" ? Object : _enums.NotificationType)
|
|
190
198
|
], NotificationResponseDto.prototype, "type", void 0);
|
|
191
199
|
_ts_decorate([
|
|
192
200
|
(0, _classtransformer.Expose)(),
|
|
193
|
-
(0, _swagger.ApiProperty)(
|
|
201
|
+
(0, _swagger.ApiProperty)({
|
|
202
|
+
description: 'Short title of the notification',
|
|
203
|
+
example: 'Your export is ready'
|
|
204
|
+
}),
|
|
194
205
|
_ts_metadata("design:type", String)
|
|
195
206
|
], NotificationResponseDto.prototype, "title", void 0);
|
|
196
207
|
_ts_decorate([
|
|
197
208
|
(0, _classtransformer.Expose)(),
|
|
198
|
-
(0, _swagger.ApiPropertyOptional)(
|
|
209
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
210
|
+
description: 'Optional longer body text for the notification',
|
|
211
|
+
example: 'Your CSV export has finished processing and is ready to download.',
|
|
212
|
+
nullable: true
|
|
213
|
+
}),
|
|
199
214
|
_ts_metadata("design:type", Object)
|
|
200
215
|
], NotificationResponseDto.prototype, "message", void 0);
|
|
201
216
|
_ts_decorate([
|
|
202
217
|
(0, _classtransformer.Expose)(),
|
|
203
|
-
(0, _swagger.ApiPropertyOptional)(
|
|
218
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
219
|
+
description: 'Arbitrary JSON payload attached to the notification',
|
|
220
|
+
type: 'object',
|
|
221
|
+
additionalProperties: true,
|
|
222
|
+
nullable: true,
|
|
223
|
+
example: {
|
|
224
|
+
exportId: 'abc123',
|
|
225
|
+
fileUrl: 'https://cdn.example.com/export.csv'
|
|
226
|
+
}
|
|
227
|
+
}),
|
|
204
228
|
_ts_metadata("design:type", Object)
|
|
205
229
|
], NotificationResponseDto.prototype, "data", void 0);
|
|
206
230
|
_ts_decorate([
|
|
207
231
|
(0, _classtransformer.Expose)(),
|
|
208
|
-
(0, _swagger.ApiProperty)(
|
|
232
|
+
(0, _swagger.ApiProperty)({
|
|
233
|
+
description: 'Whether the user has read this notification',
|
|
234
|
+
example: false
|
|
235
|
+
}),
|
|
209
236
|
_ts_metadata("design:type", Boolean)
|
|
210
237
|
], NotificationResponseDto.prototype, "isRead", void 0);
|
|
211
238
|
_ts_decorate([
|
|
212
239
|
(0, _classtransformer.Expose)(),
|
|
213
|
-
(0, _swagger.ApiPropertyOptional)(
|
|
240
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
241
|
+
description: 'Timestamp when the notification was marked as read; null if unread',
|
|
242
|
+
type: 'string',
|
|
243
|
+
format: 'date-time',
|
|
244
|
+
nullable: true,
|
|
245
|
+
example: '2024-03-15T10:30:00.000Z'
|
|
246
|
+
}),
|
|
214
247
|
_ts_metadata("design:type", Object)
|
|
215
248
|
], NotificationResponseDto.prototype, "readAt", void 0);
|
|
216
249
|
_ts_decorate([
|
|
217
250
|
(0, _classtransformer.Expose)(),
|
|
218
|
-
(0, _swagger.ApiPropertyOptional)(
|
|
251
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
252
|
+
description: 'Company scope for the notification; null for personal notifications',
|
|
253
|
+
example: '018e1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c',
|
|
254
|
+
nullable: true
|
|
255
|
+
}),
|
|
219
256
|
_ts_metadata("design:type", Object)
|
|
220
257
|
], NotificationResponseDto.prototype, "companyId", void 0);
|
|
221
258
|
_ts_decorate([
|
|
222
259
|
(0, _classtransformer.Expose)(),
|
|
223
|
-
(0, _swagger.ApiProperty)(
|
|
260
|
+
(0, _swagger.ApiProperty)({
|
|
261
|
+
description: 'Timestamp when the notification was created',
|
|
262
|
+
type: 'string',
|
|
263
|
+
format: 'date-time',
|
|
264
|
+
example: '2024-03-15T10:00:00.000Z'
|
|
265
|
+
}),
|
|
224
266
|
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
225
267
|
], NotificationResponseDto.prototype, "createdAt", void 0);
|
|
226
268
|
_ts_decorate([
|
|
227
269
|
(0, _classtransformer.Expose)(),
|
|
228
|
-
(0, _swagger.ApiProperty)(
|
|
270
|
+
(0, _swagger.ApiProperty)({
|
|
271
|
+
description: 'Timestamp when the notification was last updated',
|
|
272
|
+
type: 'string',
|
|
273
|
+
format: 'date-time',
|
|
274
|
+
example: '2024-03-15T10:30:00.000Z'
|
|
275
|
+
}),
|
|
229
276
|
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
230
277
|
], NotificationResponseDto.prototype, "updatedAt", void 0);
|
|
231
278
|
let UnreadCountResponseDto = class UnreadCountResponseDto {
|
|
@@ -235,7 +282,11 @@ let UnreadCountResponseDto = class UnreadCountResponseDto {
|
|
|
235
282
|
};
|
|
236
283
|
_ts_decorate([
|
|
237
284
|
(0, _classtransformer.Expose)(),
|
|
238
|
-
(0, _swagger.ApiProperty)(
|
|
285
|
+
(0, _swagger.ApiProperty)({
|
|
286
|
+
description: 'Total number of unread notifications for the user',
|
|
287
|
+
example: 5,
|
|
288
|
+
minimum: 0
|
|
289
|
+
}),
|
|
239
290
|
_ts_metadata("design:type", Number)
|
|
240
291
|
], UnreadCountResponseDto.prototype, "count", void 0);
|
|
241
292
|
let SendNotificationDto = class SendNotificationDto extends (0, _swagger.IntersectionType)(UserIdDto, NotificationContentDto) {
|
|
@@ -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
|
-
|
|
50
|
+
_gateways.NotificationGateway,
|
|
55
51
|
_adapters.NotificationAdapter,
|
|
56
52
|
ADAPTER_PROVIDER
|
|
57
53
|
],
|
|
58
54
|
exports: [
|
|
59
55
|
...EXPORTED_SERVICES,
|
|
60
|
-
|
|
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.
|
|
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
|
-
|
|
95
|
-
|
|
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
|
-
|
|
122
|
-
if (!this.
|
|
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(
|
|
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
|
|
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
|
|
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.
|
|
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) {
|
|
@@ -125,11 +122,11 @@ let NotificationService = class NotificationService extends _classes.RequestScop
|
|
|
125
122
|
async afterInsertOperation(entities, _user, _qr) {
|
|
126
123
|
for (const entity of entities){
|
|
127
124
|
const ext = entity;
|
|
128
|
-
this.
|
|
125
|
+
this.emitToUser(entity.userId, ext.companyId, 'notification:new', this.toPayload(entity));
|
|
129
126
|
}
|
|
130
127
|
}
|
|
131
128
|
async markAsRead(id, user) {
|
|
132
|
-
await this.
|
|
129
|
+
await this.ensureDataSourceRepository();
|
|
133
130
|
const notification = await this.repository.findOne({
|
|
134
131
|
where: {
|
|
135
132
|
id,
|
|
@@ -153,13 +150,13 @@ let NotificationService = class NotificationService extends _classes.RequestScop
|
|
|
153
150
|
]);
|
|
154
151
|
// Emit to user's sockets in the same company context
|
|
155
152
|
const ext = notification;
|
|
156
|
-
this.
|
|
153
|
+
this.emitToUser(user.id, ext.companyId ?? user.companyId, 'notification:read', {
|
|
157
154
|
id
|
|
158
155
|
});
|
|
159
156
|
return notification;
|
|
160
157
|
}
|
|
161
158
|
async markAllAsRead(user) {
|
|
162
|
-
await this.
|
|
159
|
+
await this.ensureDataSourceRepository();
|
|
163
160
|
const where = {
|
|
164
161
|
userId: user.id,
|
|
165
162
|
isRead: false
|
|
@@ -173,11 +170,11 @@ let NotificationService = class NotificationService extends _classes.RequestScop
|
|
|
173
170
|
});
|
|
174
171
|
await this.clearCacheForAll();
|
|
175
172
|
// Emit to user's sockets in the current company context
|
|
176
|
-
this.
|
|
173
|
+
this.emitToUser(user.id, user.companyId, 'notification:read-all', {});
|
|
177
174
|
return result.affected ?? 0;
|
|
178
175
|
}
|
|
179
176
|
async getUnreadCount(user) {
|
|
180
|
-
await this.
|
|
177
|
+
await this.ensureDataSourceRepository();
|
|
181
178
|
const where = {
|
|
182
179
|
userId: user.id,
|
|
183
180
|
isRead: false
|
|
@@ -199,24 +196,18 @@ let NotificationService = class NotificationService extends _classes.RequestScop
|
|
|
199
196
|
createdAt: entity.createdAt
|
|
200
197
|
};
|
|
201
198
|
}
|
|
202
|
-
|
|
203
|
-
|
|
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) {
|
|
199
|
+
emitToUser(userId, companyId, event, payload) {
|
|
200
|
+
if (!this.gateway) {
|
|
208
201
|
return;
|
|
209
202
|
}
|
|
210
203
|
if (this.notificationConfig.isCompanyFeatureEnabled() && companyId) {
|
|
211
|
-
// Company feature enabled - emit only to sockets in matching company context
|
|
212
204
|
this.gateway.emitToUserInCompany(userId, companyId, event, payload);
|
|
213
205
|
} else {
|
|
214
|
-
// No company feature or no companyId - emit to all user's sockets
|
|
215
206
|
this.gateway.emitToUser(userId, event, payload);
|
|
216
207
|
}
|
|
217
208
|
}
|
|
218
209
|
constructor(cacheManager, utilsService, notificationConfig, dataSourceProvider, gateway){
|
|
219
|
-
super('notification',
|
|
210
|
+
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
211
|
}
|
|
221
212
|
};
|
|
222
213
|
_ts_decorate([
|