@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.
- package/adapters/index.d.ts +1 -1
- package/adapters/notification.adapter.d.ts +2 -2
- package/config/index.d.ts +3 -3
- package/controllers/index.d.ts +1 -1
- package/controllers/notification.controller.d.ts +4 -4
- package/docs/index.d.ts +1 -1
- package/docs/notification-swagger.config.d.ts +2 -2
- package/dtos/index.d.ts +1 -1
- package/entities/index.d.ts +5 -5
- package/entities/notification-with-company.entity.d.ts +1 -1
- package/fesm/244.js +816 -0
- package/fesm/446.js +939 -0
- package/fesm/adapters/index.js +79 -1
- package/fesm/config/index.js +84 -3
- package/fesm/controllers/index.js +13 -1
- package/fesm/docs/index.js +112 -1
- package/fesm/dtos/index.js +311 -1
- package/fesm/entities/index.js +211 -8
- package/fesm/gateways/index.js +286 -1
- package/fesm/index.js +467 -10
- package/fesm/interfaces/index.js +16 -2
- package/fesm/modules/index.js +269 -1
- package/fesm/runtime.js +85 -0
- package/fesm/services/index.js +357 -4
- package/gateways/index.d.ts +1 -1
- package/gateways/notification.gateway.d.ts +2 -2
- package/index.d.ts +10 -10
- package/interfaces/index.d.ts +2 -2
- package/interfaces/notification-module.interface.d.ts +3 -3
- package/interfaces/notification.interface.d.ts +1 -1
- package/modules/index.d.ts +1 -1
- package/modules/notification.module.d.ts +2 -2
- package/package.json +33 -44
- package/services/index.d.ts +4 -4
- package/services/notification-config.service.d.ts +3 -3
- package/services/notification-datasource.provider.d.ts +3 -3
- package/services/notification-helper.service.d.ts +5 -5
- package/services/notification.service.d.ts +8 -8
- package/cjs/adapters/index.js +0 -18
- package/cjs/adapters/notification.adapter.js +0 -62
- package/cjs/adapters/notification.adapter.spec.js +0 -73
- package/cjs/config/event-actions.js +0 -33
- package/cjs/config/index.js +0 -20
- package/cjs/config/message-keys.js +0 -19
- package/cjs/config/notification.constants.js +0 -11
- package/cjs/controllers/index.js +0 -18
- package/cjs/controllers/notification.controller.js +0 -299
- package/cjs/controllers/notification.controller.spec.js +0 -214
- package/cjs/docs/index.js +0 -18
- package/cjs/docs/notification-swagger.config.js +0 -97
- package/cjs/docs/notification-swagger.config.spec.js +0 -68
- package/cjs/dtos/index.js +0 -18
- package/cjs/dtos/notification.dto.js +0 -295
- package/cjs/entities/index.js +0 -48
- package/cjs/entities/index.spec.js +0 -13
- package/cjs/entities/notification-with-company.entity.js +0 -57
- package/cjs/entities/notification.entity.js +0 -112
- package/cjs/gateways/index.js +0 -18
- package/cjs/gateways/notification.gateway.js +0 -172
- package/cjs/gateways/notification.gateway.spec.js +0 -359
- package/cjs/index.js +0 -28
- package/cjs/interfaces/index.js +0 -19
- package/cjs/interfaces/notification-module.interface.js +0 -4
- package/cjs/interfaces/notification.interface.js +0 -4
- package/cjs/modules/index.js +0 -18
- package/cjs/modules/notification.module.js +0 -139
- package/cjs/modules/notification.module.spec.js +0 -152
- package/cjs/services/index.js +0 -21
- package/cjs/services/notification-config.service.js +0 -69
- package/cjs/services/notification-config.service.spec.js +0 -113
- package/cjs/services/notification-datasource.provider.js +0 -133
- package/cjs/services/notification-datasource.provider.spec.js +0 -136
- package/cjs/services/notification-helper.service.js +0 -197
- package/cjs/services/notification-helper.service.spec.js +0 -392
- package/cjs/services/notification.service.js +0 -281
- package/cjs/services/notification.service.spec.js +0 -560
- package/fesm/adapters/notification.adapter.js +0 -52
- package/fesm/adapters/notification.adapter.spec.js +0 -69
- package/fesm/config/event-actions.js +0 -12
- package/fesm/config/message-keys.js +0 -9
- package/fesm/config/notification.constants.js +0 -1
- package/fesm/controllers/notification.controller.js +0 -289
- package/fesm/controllers/notification.controller.spec.js +0 -210
- package/fesm/docs/notification-swagger.config.js +0 -87
- package/fesm/docs/notification-swagger.config.spec.js +0 -64
- package/fesm/dtos/notification.dto.js +0 -262
- package/fesm/entities/index.spec.js +0 -9
- package/fesm/entities/notification-with-company.entity.js +0 -47
- package/fesm/entities/notification.entity.js +0 -102
- package/fesm/gateways/notification.gateway.js +0 -162
- package/fesm/gateways/notification.gateway.spec.js +0 -355
- package/fesm/interfaces/notification-module.interface.js +0 -1
- package/fesm/interfaces/notification.interface.js +0 -1
- package/fesm/modules/notification.module.js +0 -129
- package/fesm/modules/notification.module.spec.js +0 -148
- package/fesm/services/notification-config.service.js +0 -59
- package/fesm/services/notification-config.service.spec.js +0 -109
- package/fesm/services/notification-datasource.provider.js +0 -82
- package/fesm/services/notification-datasource.provider.spec.js +0 -132
- package/fesm/services/notification-helper.service.js +0 -187
- package/fesm/services/notification-helper.service.spec.js +0 -388
- package/fesm/services/notification.service.js +0 -271
- package/fesm/services/notification.service.spec.js +0 -556
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
15
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
-
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;
|
|
18
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
|
-
}
|
|
20
|
-
function _ts_metadata(k, v) {
|
|
21
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
-
}
|
|
23
|
-
function _ts_param(paramIndex, decorator) {
|
|
24
|
-
return function(target, key) {
|
|
25
|
-
decorator(target, key, paramIndex);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
import { Inject, Injectable } from '@nestjs/common';
|
|
29
|
-
import { NotificationModuleOptions } from '../interfaces';
|
|
30
|
-
import { NOTIFICATION_MODULE_OPTIONS } from '../config/notification.constants';
|
|
31
|
-
export class NotificationConfigService {
|
|
32
|
-
isCompanyFeatureEnabled() {
|
|
33
|
-
return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
|
|
34
|
-
}
|
|
35
|
-
getDatabaseMode() {
|
|
36
|
-
return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
|
|
37
|
-
}
|
|
38
|
-
isMultiTenant() {
|
|
39
|
-
return this.getDatabaseMode() === 'multi-tenant';
|
|
40
|
-
}
|
|
41
|
-
getJwtSecret() {
|
|
42
|
-
return this.options.config?.jwtSecret;
|
|
43
|
-
}
|
|
44
|
-
getOptions() {
|
|
45
|
-
return this.options;
|
|
46
|
-
}
|
|
47
|
-
constructor(options){
|
|
48
|
-
_define_property(this, "options", void 0);
|
|
49
|
-
this.options = options;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
NotificationConfigService = _ts_decorate([
|
|
53
|
-
Injectable(),
|
|
54
|
-
_ts_param(0, Inject(NOTIFICATION_MODULE_OPTIONS)),
|
|
55
|
-
_ts_metadata("design:type", Function),
|
|
56
|
-
_ts_metadata("design:paramtypes", [
|
|
57
|
-
typeof NotificationModuleOptions === "undefined" ? Object : NotificationModuleOptions
|
|
58
|
-
])
|
|
59
|
-
], NotificationConfigService);
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { NotificationConfigService } from './notification-config.service';
|
|
2
|
-
function buildOptions(overrides = {}) {
|
|
3
|
-
return {
|
|
4
|
-
bootstrapAppConfig: {
|
|
5
|
-
databaseMode: 'single',
|
|
6
|
-
enableCompanyFeature: false
|
|
7
|
-
},
|
|
8
|
-
config: {},
|
|
9
|
-
...overrides
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
describe('NotificationConfigService', ()=>{
|
|
13
|
-
describe('isCompanyFeatureEnabled', ()=>{
|
|
14
|
-
it('returns true when bootstrapAppConfig enables the company feature', ()=>{
|
|
15
|
-
const service = new NotificationConfigService(buildOptions({
|
|
16
|
-
bootstrapAppConfig: {
|
|
17
|
-
databaseMode: 'single',
|
|
18
|
-
enableCompanyFeature: true
|
|
19
|
-
}
|
|
20
|
-
}));
|
|
21
|
-
expect(service.isCompanyFeatureEnabled()).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
it('returns false when bootstrapAppConfig disables the company feature', ()=>{
|
|
24
|
-
const service = new NotificationConfigService(buildOptions({
|
|
25
|
-
bootstrapAppConfig: {
|
|
26
|
-
databaseMode: 'single',
|
|
27
|
-
enableCompanyFeature: false
|
|
28
|
-
}
|
|
29
|
-
}));
|
|
30
|
-
expect(service.isCompanyFeatureEnabled()).toBe(false);
|
|
31
|
-
});
|
|
32
|
-
it('defaults to false when bootstrapAppConfig is missing', ()=>{
|
|
33
|
-
const service = new NotificationConfigService(buildOptions({
|
|
34
|
-
bootstrapAppConfig: undefined
|
|
35
|
-
}));
|
|
36
|
-
expect(service.isCompanyFeatureEnabled()).toBe(false);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('getDatabaseMode', ()=>{
|
|
40
|
-
it('returns the configured database mode', ()=>{
|
|
41
|
-
const service = new NotificationConfigService(buildOptions({
|
|
42
|
-
bootstrapAppConfig: {
|
|
43
|
-
databaseMode: 'multi-tenant',
|
|
44
|
-
enableCompanyFeature: true
|
|
45
|
-
}
|
|
46
|
-
}));
|
|
47
|
-
expect(service.getDatabaseMode()).toBe('multi-tenant');
|
|
48
|
-
});
|
|
49
|
-
it('defaults to "single" when bootstrapAppConfig is missing', ()=>{
|
|
50
|
-
const service = new NotificationConfigService(buildOptions({
|
|
51
|
-
bootstrapAppConfig: undefined
|
|
52
|
-
}));
|
|
53
|
-
expect(service.getDatabaseMode()).toBe('single');
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
describe('isMultiTenant', ()=>{
|
|
57
|
-
it('returns true when database mode is multi-tenant', ()=>{
|
|
58
|
-
const service = new NotificationConfigService(buildOptions({
|
|
59
|
-
bootstrapAppConfig: {
|
|
60
|
-
databaseMode: 'multi-tenant',
|
|
61
|
-
enableCompanyFeature: true
|
|
62
|
-
}
|
|
63
|
-
}));
|
|
64
|
-
expect(service.isMultiTenant()).toBe(true);
|
|
65
|
-
});
|
|
66
|
-
it('returns false when database mode is single', ()=>{
|
|
67
|
-
const service = new NotificationConfigService(buildOptions({
|
|
68
|
-
bootstrapAppConfig: {
|
|
69
|
-
databaseMode: 'single',
|
|
70
|
-
enableCompanyFeature: false
|
|
71
|
-
}
|
|
72
|
-
}));
|
|
73
|
-
expect(service.isMultiTenant()).toBe(false);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe('getJwtSecret', ()=>{
|
|
77
|
-
it('returns the configured jwt secret', ()=>{
|
|
78
|
-
const service = new NotificationConfigService(buildOptions({
|
|
79
|
-
config: {
|
|
80
|
-
jwtSecret: 'top-secret'
|
|
81
|
-
}
|
|
82
|
-
}));
|
|
83
|
-
expect(service.getJwtSecret()).toBe('top-secret');
|
|
84
|
-
});
|
|
85
|
-
it('returns undefined when no jwt secret is configured', ()=>{
|
|
86
|
-
const service = new NotificationConfigService(buildOptions({
|
|
87
|
-
config: {}
|
|
88
|
-
}));
|
|
89
|
-
expect(service.getJwtSecret()).toBeUndefined();
|
|
90
|
-
});
|
|
91
|
-
it('returns undefined when config is missing entirely', ()=>{
|
|
92
|
-
const service = new NotificationConfigService(buildOptions({
|
|
93
|
-
config: undefined
|
|
94
|
-
}));
|
|
95
|
-
expect(service.getJwtSecret()).toBeUndefined();
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
describe('getOptions', ()=>{
|
|
99
|
-
it('returns the raw options object passed to the constructor', ()=>{
|
|
100
|
-
const options = buildOptions({
|
|
101
|
-
config: {
|
|
102
|
-
jwtSecret: 'abc'
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
const service = new NotificationConfigService(options);
|
|
106
|
-
expect(service.getOptions()).toBe(options);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
});
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
15
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
-
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;
|
|
18
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
|
-
}
|
|
20
|
-
function _ts_metadata(k, v) {
|
|
21
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
-
}
|
|
23
|
-
function _ts_param(paramIndex, decorator) {
|
|
24
|
-
return function(target, key) {
|
|
25
|
-
decorator(target, key, paramIndex);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
29
|
-
import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
|
|
30
|
-
import { REQUEST } from '@nestjs/core';
|
|
31
|
-
import { Request } from 'express';
|
|
32
|
-
import { NotificationConfigService } from './notification-config.service';
|
|
33
|
-
export class NotificationDataSourceProvider extends MultiTenantDataSourceService {
|
|
34
|
-
static buildParentOptions(options) {
|
|
35
|
-
return {
|
|
36
|
-
bootstrapAppConfig: options.bootstrapAppConfig,
|
|
37
|
-
defaultDatabaseConfig: options.config?.defaultDatabaseConfig,
|
|
38
|
-
tenantDefaultDatabaseConfig: options.config?.tenantDefaultDatabaseConfig,
|
|
39
|
-
tenants: options.config?.tenants
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
getEnableCompanyFeatureForTenant(tenant) {
|
|
43
|
-
return tenant?.enableCompanyFeature ?? this.configService.isCompanyFeatureEnabled();
|
|
44
|
-
}
|
|
45
|
-
async getNotificationEntities(enableCompanyFeature) {
|
|
46
|
-
const enable = enableCompanyFeature ?? this.configService.isCompanyFeatureEnabled();
|
|
47
|
-
const entities = await import('../entities');
|
|
48
|
-
return enable ? [
|
|
49
|
-
entities.NotificationWithCompany
|
|
50
|
-
] : [
|
|
51
|
-
entities.Notification
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
async createDataSourceFromConfig(config) {
|
|
55
|
-
const currentTenant = this.getCurrentTenant();
|
|
56
|
-
const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
|
|
57
|
-
const entities = await this.getNotificationEntities(enableCompanyFeature);
|
|
58
|
-
return super.createDataSourceFromConfig(config, entities);
|
|
59
|
-
}
|
|
60
|
-
constructor(configService, request){
|
|
61
|
-
super(NotificationDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
_define_property(NotificationDataSourceProvider, "tenantConnections", new Map());
|
|
65
|
-
_define_property(NotificationDataSourceProvider, "singleDataSource", null);
|
|
66
|
-
_define_property(NotificationDataSourceProvider, "tenantsRegistry", new Map());
|
|
67
|
-
_define_property(NotificationDataSourceProvider, "initialized", false);
|
|
68
|
-
_define_property(NotificationDataSourceProvider, "connectionLocks", new Map());
|
|
69
|
-
_define_property(NotificationDataSourceProvider, "singleConnectionLock", null);
|
|
70
|
-
NotificationDataSourceProvider = _ts_decorate([
|
|
71
|
-
Injectable({
|
|
72
|
-
scope: Scope.REQUEST
|
|
73
|
-
}),
|
|
74
|
-
_ts_param(0, Inject(NotificationConfigService)),
|
|
75
|
-
_ts_param(1, Optional()),
|
|
76
|
-
_ts_param(1, Inject(REQUEST)),
|
|
77
|
-
_ts_metadata("design:type", Function),
|
|
78
|
-
_ts_metadata("design:paramtypes", [
|
|
79
|
-
typeof NotificationConfigService === "undefined" ? Object : NotificationConfigService,
|
|
80
|
-
typeof Request === "undefined" ? Object : Request
|
|
81
|
-
])
|
|
82
|
-
], NotificationDataSourceProvider);
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
2
|
-
import { NotificationDataSourceProvider } from './notification-datasource.provider';
|
|
3
|
-
import { Notification, NotificationWithCompany } from '../entities';
|
|
4
|
-
function buildConfigService(overrides = {}) {
|
|
5
|
-
return {
|
|
6
|
-
isCompanyFeatureEnabled: jest.fn().mockReturnValue(false),
|
|
7
|
-
getDatabaseMode: jest.fn().mockReturnValue('single'),
|
|
8
|
-
isMultiTenant: jest.fn().mockReturnValue(false),
|
|
9
|
-
getJwtSecret: jest.fn().mockReturnValue(undefined),
|
|
10
|
-
getOptions: jest.fn().mockReturnValue({
|
|
11
|
-
bootstrapAppConfig: {
|
|
12
|
-
databaseMode: 'single',
|
|
13
|
-
enableCompanyFeature: false
|
|
14
|
-
},
|
|
15
|
-
config: {
|
|
16
|
-
defaultDatabaseConfig: {
|
|
17
|
-
type: 'mysql',
|
|
18
|
-
host: 'localhost',
|
|
19
|
-
port: 3306,
|
|
20
|
-
username: 'root',
|
|
21
|
-
password: 'pass',
|
|
22
|
-
database: 'flusys'
|
|
23
|
-
},
|
|
24
|
-
tenants: []
|
|
25
|
-
}
|
|
26
|
-
}),
|
|
27
|
-
...overrides
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
describe('NotificationDataSourceProvider', ()=>{
|
|
31
|
-
let configService;
|
|
32
|
-
let provider;
|
|
33
|
-
beforeEach(()=>{
|
|
34
|
-
configService = buildConfigService();
|
|
35
|
-
provider = new NotificationDataSourceProvider(configService, undefined);
|
|
36
|
-
});
|
|
37
|
-
describe('getEnableCompanyFeatureForTenant', ()=>{
|
|
38
|
-
it('returns the tenant override when the tenant explicitly enables the company feature', ()=>{
|
|
39
|
-
const result = provider.getEnableCompanyFeatureForTenant({
|
|
40
|
-
id: 'tenant-1',
|
|
41
|
-
database: 'tenant_db',
|
|
42
|
-
enableCompanyFeature: true
|
|
43
|
-
});
|
|
44
|
-
expect(result).toBe(true);
|
|
45
|
-
expect(configService.isCompanyFeatureEnabled).not.toHaveBeenCalled();
|
|
46
|
-
});
|
|
47
|
-
it('returns the tenant override when the tenant explicitly disables the company feature', ()=>{
|
|
48
|
-
const result = provider.getEnableCompanyFeatureForTenant({
|
|
49
|
-
id: 'tenant-1',
|
|
50
|
-
database: 'tenant_db',
|
|
51
|
-
enableCompanyFeature: false
|
|
52
|
-
});
|
|
53
|
-
expect(result).toBe(false);
|
|
54
|
-
});
|
|
55
|
-
it('falls back to the config service when the tenant has no override', ()=>{
|
|
56
|
-
configService.isCompanyFeatureEnabled.mockReturnValue(true);
|
|
57
|
-
const result = provider.getEnableCompanyFeatureForTenant(undefined);
|
|
58
|
-
expect(result).toBe(true);
|
|
59
|
-
expect(configService.isCompanyFeatureEnabled).toHaveBeenCalled();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe('getNotificationEntities', ()=>{
|
|
63
|
-
it('returns [NotificationWithCompany] when enableCompanyFeature is explicitly true', async ()=>{
|
|
64
|
-
const entities = await provider.getNotificationEntities(true);
|
|
65
|
-
expect(entities).toEqual([
|
|
66
|
-
NotificationWithCompany
|
|
67
|
-
]);
|
|
68
|
-
});
|
|
69
|
-
it('returns [Notification] when enableCompanyFeature is explicitly false', async ()=>{
|
|
70
|
-
const entities = await provider.getNotificationEntities(false);
|
|
71
|
-
expect(entities).toEqual([
|
|
72
|
-
Notification
|
|
73
|
-
]);
|
|
74
|
-
});
|
|
75
|
-
it('falls back to the config service when enableCompanyFeature is not provided', async ()=>{
|
|
76
|
-
configService.isCompanyFeatureEnabled.mockReturnValue(true);
|
|
77
|
-
const entities = await provider.getNotificationEntities();
|
|
78
|
-
expect(entities).toEqual([
|
|
79
|
-
NotificationWithCompany
|
|
80
|
-
]);
|
|
81
|
-
expect(configService.isCompanyFeatureEnabled).toHaveBeenCalled();
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('createDataSourceFromConfig', ()=>{
|
|
85
|
-
it('resolves company-aware entities and delegates to the parent implementation', async ()=>{
|
|
86
|
-
configService.isCompanyFeatureEnabled.mockReturnValue(true);
|
|
87
|
-
const fakeDataSource = {};
|
|
88
|
-
const superSpy = jest.spyOn(MultiTenantDataSourceService.prototype, 'createDataSourceFromConfig').mockResolvedValue(fakeDataSource);
|
|
89
|
-
const config = {
|
|
90
|
-
type: 'mysql',
|
|
91
|
-
host: 'localhost',
|
|
92
|
-
port: 3306,
|
|
93
|
-
username: 'root',
|
|
94
|
-
password: 'pass',
|
|
95
|
-
database: 'flusys'
|
|
96
|
-
};
|
|
97
|
-
const result = await provider.createDataSourceFromConfig(config);
|
|
98
|
-
expect(result).toBe(fakeDataSource);
|
|
99
|
-
expect(superSpy).toHaveBeenCalledWith(config, [
|
|
100
|
-
NotificationWithCompany
|
|
101
|
-
]);
|
|
102
|
-
superSpy.mockRestore();
|
|
103
|
-
});
|
|
104
|
-
it('resolves core entities when the company feature is disabled', async ()=>{
|
|
105
|
-
configService.isCompanyFeatureEnabled.mockReturnValue(false);
|
|
106
|
-
const fakeDataSource = {};
|
|
107
|
-
const superSpy = jest.spyOn(MultiTenantDataSourceService.prototype, 'createDataSourceFromConfig').mockResolvedValue(fakeDataSource);
|
|
108
|
-
const config = {
|
|
109
|
-
type: 'mysql',
|
|
110
|
-
host: 'localhost',
|
|
111
|
-
port: 3306,
|
|
112
|
-
username: 'root',
|
|
113
|
-
password: 'pass',
|
|
114
|
-
database: 'flusys'
|
|
115
|
-
};
|
|
116
|
-
await provider.createDataSourceFromConfig(config);
|
|
117
|
-
expect(superSpy).toHaveBeenCalledWith(config, [
|
|
118
|
-
Notification
|
|
119
|
-
]);
|
|
120
|
-
superSpy.mockRestore();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
describe('inherited configuration accessors', ()=>{
|
|
124
|
-
it('reports single database mode by default', ()=>{
|
|
125
|
-
expect(provider.getDatabaseMode()).toBe('single');
|
|
126
|
-
expect(provider.isMultiTenant()).toBe(false);
|
|
127
|
-
});
|
|
128
|
-
it('returns null for the current tenant when no request is bound', ()=>{
|
|
129
|
-
expect(provider.getCurrentTenant()).toBeNull();
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
});
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
15
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
16
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
17
|
-
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;
|
|
18
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
19
|
-
}
|
|
20
|
-
function _ts_metadata(k, v) {
|
|
21
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
|
-
}
|
|
23
|
-
function _ts_param(paramIndex, decorator) {
|
|
24
|
-
return function(target, key) {
|
|
25
|
-
decorator(target, key, paramIndex);
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
import { INotificationBulkSendOptions, INotificationSendOptions, LogAction } from '@flusys/nestjs-shared';
|
|
29
|
-
import { HybridCache, publishDomainEvent } from '@flusys/nestjs-shared/classes';
|
|
30
|
-
import { NotificationType } from '@flusys/nestjs-shared/enums';
|
|
31
|
-
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
32
|
-
import { Inject, Injectable, Optional } from '@nestjs/common';
|
|
33
|
-
import { NOTIFICATION_EVENT_ACTIONS, NOTIFICATION_EVENT_ENTITIES, NOTIFICATION_EVENT_MODULE } from '../config';
|
|
34
|
-
import { Notification, NotificationWithCompany } from '../entities';
|
|
35
|
-
import { NotificationGateway } from '../gateways';
|
|
36
|
-
import { NotificationConfigService } from './notification-config.service';
|
|
37
|
-
import { NotificationDataSourceProvider } from './notification-datasource.provider';
|
|
38
|
-
export class NotificationHelperService {
|
|
39
|
-
async send(options) {
|
|
40
|
-
const repo = await this.getRepository();
|
|
41
|
-
const entity = this.buildEntity(options.userId, options);
|
|
42
|
-
const saved = await repo.save(entity);
|
|
43
|
-
await this.clearCache();
|
|
44
|
-
this.emitToUser(saved, options.realtime !== false);
|
|
45
|
-
await this.publishSentEvent([
|
|
46
|
-
saved
|
|
47
|
-
], [
|
|
48
|
-
options.userId
|
|
49
|
-
]);
|
|
50
|
-
return saved;
|
|
51
|
-
}
|
|
52
|
-
async sendToMany(options) {
|
|
53
|
-
const repo = await this.getRepository();
|
|
54
|
-
const entities = options.userIds.map((userId)=>this.buildEntity(userId, options));
|
|
55
|
-
const saved = await repo.save(entities);
|
|
56
|
-
await this.clearCache();
|
|
57
|
-
if (options.realtime !== false) {
|
|
58
|
-
setImmediate(()=>{
|
|
59
|
-
for (const notification of saved){
|
|
60
|
-
this.emitToUser(notification, true);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
await this.publishSentEvent(saved, options.userIds);
|
|
65
|
-
return saved;
|
|
66
|
-
}
|
|
67
|
-
isUserOnline(userId) {
|
|
68
|
-
return this.gateway?.isUserOnline(userId) ?? false;
|
|
69
|
-
}
|
|
70
|
-
getOnlineUserCount() {
|
|
71
|
-
return this.gateway?.getOnlineUserCount() ?? 0;
|
|
72
|
-
}
|
|
73
|
-
async publishSentEvent(notifications, userIds) {
|
|
74
|
-
await publishDomainEvent({
|
|
75
|
-
module: NOTIFICATION_EVENT_MODULE,
|
|
76
|
-
entity: NOTIFICATION_EVENT_ENTITIES.NOTIFICATION,
|
|
77
|
-
action: NOTIFICATION_EVENT_ACTIONS.SENT,
|
|
78
|
-
ids: notifications.map((notification)=>notification.id),
|
|
79
|
-
metadata: {
|
|
80
|
-
recipientCount: userIds.length
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
async getDataSource() {
|
|
85
|
-
if (!this.dataSource) {
|
|
86
|
-
this.dataSource = await this.dataSourceProvider.getDataSource();
|
|
87
|
-
}
|
|
88
|
-
return this.dataSource;
|
|
89
|
-
}
|
|
90
|
-
async getRepository() {
|
|
91
|
-
const ds = await this.getDataSource();
|
|
92
|
-
const EntityClass = this.configService.isCompanyFeatureEnabled() ? NotificationWithCompany : Notification;
|
|
93
|
-
return ds.getRepository(EntityClass);
|
|
94
|
-
}
|
|
95
|
-
buildEntity(userId, content) {
|
|
96
|
-
const entity = {
|
|
97
|
-
userId,
|
|
98
|
-
type: content.type ?? NotificationType.INFO,
|
|
99
|
-
title: content.title,
|
|
100
|
-
message: content.message ?? null,
|
|
101
|
-
data: content.data ?? null,
|
|
102
|
-
isRead: false
|
|
103
|
-
};
|
|
104
|
-
if (this.configService.isCompanyFeatureEnabled() && content.companyId) {
|
|
105
|
-
entity.companyId = content.companyId;
|
|
106
|
-
}
|
|
107
|
-
return entity;
|
|
108
|
-
}
|
|
109
|
-
emitToUser(notification, realtime) {
|
|
110
|
-
if (!realtime || !this.gateway) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const ext = notification;
|
|
114
|
-
const payload = this.toPayload(notification);
|
|
115
|
-
if (this.configService.isCompanyFeatureEnabled() && ext.companyId) {
|
|
116
|
-
this.gateway.emitToUserInCompany(notification.userId, ext.companyId, 'notification:new', payload);
|
|
117
|
-
} else {
|
|
118
|
-
this.gateway.emitToUser(notification.userId, 'notification:new', payload);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
toPayload(notification) {
|
|
122
|
-
return {
|
|
123
|
-
id: notification.id,
|
|
124
|
-
type: notification.type,
|
|
125
|
-
title: notification.title,
|
|
126
|
-
message: notification.message,
|
|
127
|
-
data: notification.data,
|
|
128
|
-
createdAt: notification.createdAt
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
async clearCache() {
|
|
132
|
-
await this.utilsService.clearCache(NOTIFICATION_EVENT_ENTITIES.NOTIFICATION, this.cacheManager);
|
|
133
|
-
}
|
|
134
|
-
constructor(cacheManager, utilsService, configService, dataSourceProvider, gateway){
|
|
135
|
-
_define_property(this, "cacheManager", void 0);
|
|
136
|
-
_define_property(this, "utilsService", void 0);
|
|
137
|
-
_define_property(this, "configService", void 0);
|
|
138
|
-
_define_property(this, "dataSourceProvider", void 0);
|
|
139
|
-
_define_property(this, "gateway", void 0);
|
|
140
|
-
_define_property(this, "dataSource", void 0);
|
|
141
|
-
this.cacheManager = cacheManager;
|
|
142
|
-
this.utilsService = utilsService;
|
|
143
|
-
this.configService = configService;
|
|
144
|
-
this.dataSourceProvider = dataSourceProvider;
|
|
145
|
-
this.gateway = gateway;
|
|
146
|
-
this.dataSource = null;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
_ts_decorate([
|
|
150
|
-
LogAction({
|
|
151
|
-
action: 'notification.send',
|
|
152
|
-
module: 'notification'
|
|
153
|
-
}),
|
|
154
|
-
_ts_metadata("design:type", Function),
|
|
155
|
-
_ts_metadata("design:paramtypes", [
|
|
156
|
-
typeof INotificationSendOptions === "undefined" ? Object : INotificationSendOptions
|
|
157
|
-
]),
|
|
158
|
-
_ts_metadata("design:returntype", Promise)
|
|
159
|
-
], NotificationHelperService.prototype, "send", null);
|
|
160
|
-
_ts_decorate([
|
|
161
|
-
LogAction({
|
|
162
|
-
action: 'notification.sendToMany',
|
|
163
|
-
module: 'notification'
|
|
164
|
-
}),
|
|
165
|
-
_ts_metadata("design:type", Function),
|
|
166
|
-
_ts_metadata("design:paramtypes", [
|
|
167
|
-
typeof INotificationBulkSendOptions === "undefined" ? Object : INotificationBulkSendOptions
|
|
168
|
-
]),
|
|
169
|
-
_ts_metadata("design:returntype", Promise)
|
|
170
|
-
], NotificationHelperService.prototype, "sendToMany", null);
|
|
171
|
-
NotificationHelperService = _ts_decorate([
|
|
172
|
-
Injectable(),
|
|
173
|
-
_ts_param(0, Inject('CACHE_INSTANCE')),
|
|
174
|
-
_ts_param(1, Inject(UtilsService)),
|
|
175
|
-
_ts_param(2, Inject(NotificationConfigService)),
|
|
176
|
-
_ts_param(3, Inject(NotificationDataSourceProvider)),
|
|
177
|
-
_ts_param(4, Optional()),
|
|
178
|
-
_ts_param(4, Inject(NotificationGateway)),
|
|
179
|
-
_ts_metadata("design:type", Function),
|
|
180
|
-
_ts_metadata("design:paramtypes", [
|
|
181
|
-
typeof HybridCache === "undefined" ? Object : HybridCache,
|
|
182
|
-
typeof UtilsService === "undefined" ? Object : UtilsService,
|
|
183
|
-
typeof NotificationConfigService === "undefined" ? Object : NotificationConfigService,
|
|
184
|
-
typeof NotificationDataSourceProvider === "undefined" ? Object : NotificationDataSourceProvider,
|
|
185
|
-
typeof NotificationGateway === "undefined" ? Object : NotificationGateway
|
|
186
|
-
])
|
|
187
|
-
], NotificationHelperService);
|