@flusys/nestjs-event-manager 7.0.2 → 8.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/adapters/event-manager.adapter.d.ts +2 -2
  2. package/adapters/index.d.ts +1 -1
  3. package/config/index.d.ts +3 -3
  4. package/controllers/event.controller.d.ts +3 -3
  5. package/controllers/index.d.ts +1 -1
  6. package/docs/event-manager-swagger.config.d.ts +2 -2
  7. package/docs/index.d.ts +1 -1
  8. package/dtos/calendar-query.dto.d.ts +1 -1
  9. package/dtos/event.dto.d.ts +1 -1
  10. package/dtos/index.d.ts +3 -3
  11. package/entities/event-with-company.entity.d.ts +1 -1
  12. package/entities/index.d.ts +8 -8
  13. package/fesm/477.js +1798 -0
  14. package/fesm/833.js +840 -0
  15. package/fesm/adapters/index.js +884 -1
  16. package/fesm/config/index.js +87 -3
  17. package/fesm/controllers/index.js +365 -1
  18. package/fesm/docs/index.js +155 -2
  19. package/fesm/dtos/index.js +720 -3
  20. package/fesm/entities/index.js +350 -11
  21. package/fesm/index.js +121 -9
  22. package/fesm/interfaces/index.js +16 -2
  23. package/fesm/modules/index.js +13 -1
  24. package/fesm/runtime.js +85 -0
  25. package/fesm/services/index.js +272 -4
  26. package/index.d.ts +9 -9
  27. package/interfaces/event-manager-module.interface.d.ts +3 -3
  28. package/interfaces/event.interface.d.ts +1 -1
  29. package/interfaces/index.d.ts +2 -2
  30. package/modules/event-manager.module.d.ts +2 -2
  31. package/modules/index.d.ts +1 -1
  32. package/package.json +29 -39
  33. package/services/event-manager-config.service.d.ts +3 -3
  34. package/services/event-manager-datasource.provider.d.ts +3 -3
  35. package/services/event-manager-helper.service.d.ts +3 -3
  36. package/services/event.service.d.ts +7 -7
  37. package/services/index.d.ts +4 -4
  38. package/cjs/adapters/event-manager.adapter.js +0 -65
  39. package/cjs/adapters/event-manager.adapter.spec.js +0 -104
  40. package/cjs/adapters/index.js +0 -18
  41. package/cjs/config/event-actions.js +0 -31
  42. package/cjs/config/event-manager.constants.js +0 -13
  43. package/cjs/config/index.js +0 -20
  44. package/cjs/config/message-keys.js +0 -27
  45. package/cjs/controllers/event.controller.js +0 -190
  46. package/cjs/controllers/event.controller.spec.js +0 -156
  47. package/cjs/controllers/index.js +0 -18
  48. package/cjs/docs/event-manager-swagger.config.js +0 -125
  49. package/cjs/docs/event-manager-swagger.config.spec.js +0 -65
  50. package/cjs/docs/index.js +0 -21
  51. package/cjs/dtos/calendar-query.dto.js +0 -212
  52. package/cjs/dtos/event-participant.dto.js +0 -181
  53. package/cjs/dtos/event.dto.js +0 -343
  54. package/cjs/dtos/index.js +0 -20
  55. package/cjs/entities/event-participant.entity.js +0 -89
  56. package/cjs/entities/event-with-company.entity.js +0 -56
  57. package/cjs/entities/event.entity.js +0 -156
  58. package/cjs/entities/index.js +0 -55
  59. package/cjs/entities/index.spec.js +0 -18
  60. package/cjs/index.js +0 -27
  61. package/cjs/interfaces/event-manager-module.interface.js +0 -4
  62. package/cjs/interfaces/event.interface.js +0 -4
  63. package/cjs/interfaces/index.js +0 -19
  64. package/cjs/modules/event-manager.module.js +0 -132
  65. package/cjs/modules/event-manager.module.spec.js +0 -146
  66. package/cjs/modules/index.js +0 -18
  67. package/cjs/services/event-manager-config.service.js +0 -76
  68. package/cjs/services/event-manager-config.service.spec.js +0 -111
  69. package/cjs/services/event-manager-datasource.provider.js +0 -84
  70. package/cjs/services/event-manager-datasource.provider.spec.js +0 -198
  71. package/cjs/services/event-manager-helper.service.js +0 -235
  72. package/cjs/services/event-manager-helper.service.spec.js +0 -327
  73. package/cjs/services/event.service.js +0 -481
  74. package/cjs/services/event.service.spec.js +0 -929
  75. package/cjs/services/index.js +0 -21
  76. package/fesm/adapters/event-manager.adapter.js +0 -55
  77. package/fesm/adapters/event-manager.adapter.spec.js +0 -100
  78. package/fesm/config/event-actions.js +0 -10
  79. package/fesm/config/event-manager.constants.js +0 -3
  80. package/fesm/config/message-keys.js +0 -9
  81. package/fesm/controllers/event.controller.js +0 -180
  82. package/fesm/controllers/event.controller.spec.js +0 -152
  83. package/fesm/docs/event-manager-swagger.config.js +0 -118
  84. package/fesm/docs/event-manager-swagger.config.spec.js +0 -61
  85. package/fesm/dtos/calendar-query.dto.js +0 -194
  86. package/fesm/dtos/event-participant.dto.js +0 -157
  87. package/fesm/dtos/event.dto.js +0 -322
  88. package/fesm/entities/event-participant.entity.js +0 -79
  89. package/fesm/entities/event-with-company.entity.js +0 -46
  90. package/fesm/entities/event.entity.js +0 -146
  91. package/fesm/entities/index.spec.js +0 -14
  92. package/fesm/interfaces/event-manager-module.interface.js +0 -3
  93. package/fesm/interfaces/event.interface.js +0 -1
  94. package/fesm/modules/event-manager.module.js +0 -122
  95. package/fesm/modules/event-manager.module.spec.js +0 -142
  96. package/fesm/services/event-manager-config.service.js +0 -66
  97. package/fesm/services/event-manager-config.service.spec.js +0 -107
  98. package/fesm/services/event-manager-datasource.provider.js +0 -74
  99. package/fesm/services/event-manager-datasource.provider.spec.js +0 -194
  100. package/fesm/services/event-manager-helper.service.js +0 -225
  101. package/fesm/services/event-manager-helper.service.spec.js +0 -323
  102. package/fesm/services/event.service.js +0 -471
  103. package/fesm/services/event.service.spec.js +0 -925
@@ -1,194 +0,0 @@
1
- import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
2
- import { Event, EventParticipant, EventWithCompany } from '../entities';
3
- import { EventManagerDataSourceProvider } from './event-manager-datasource.provider';
4
- function buildConfigService(overrides = {}) {
5
- return {
6
- isCompanyFeatureEnabled: jest.fn().mockReturnValue(overrides.isCompanyFeatureEnabled ?? false),
7
- getDatabaseMode: jest.fn().mockReturnValue('single'),
8
- isMultiTenant: jest.fn().mockReturnValue(false),
9
- getDefaultColor: jest.fn(),
10
- getMaxRecurrenceOccurrences: jest.fn(),
11
- getOptions: jest.fn().mockReturnValue(overrides.options ?? {
12
- bootstrapAppConfig: {
13
- enableCompanyFeature: false,
14
- databaseMode: 'single'
15
- },
16
- config: {
17
- defaultDatabaseConfig: {
18
- type: 'mysql',
19
- host: 'localhost'
20
- },
21
- tenantDefaultDatabaseConfig: undefined,
22
- tenants: []
23
- }
24
- })
25
- };
26
- }
27
- describe('EventManagerDataSourceProvider', ()=>{
28
- afterEach(()=>{
29
- jest.restoreAllMocks();
30
- });
31
- describe('constructor / buildParentOptions', ()=>{
32
- it('maps module options to the parent IDataSourceServiceOptions shape', ()=>{
33
- const configService = buildConfigService({
34
- options: {
35
- bootstrapAppConfig: {
36
- enableCompanyFeature: true,
37
- databaseMode: 'multi-tenant'
38
- },
39
- config: {
40
- defaultDatabaseConfig: {
41
- type: 'mysql',
42
- host: 'db-host'
43
- },
44
- tenantDefaultDatabaseConfig: {
45
- type: 'mysql',
46
- host: 'tenant-host'
47
- },
48
- tenants: [
49
- {
50
- id: 'tenant-1',
51
- database: 'tenant_db'
52
- }
53
- ]
54
- }
55
- }
56
- });
57
- const provider = new EventManagerDataSourceProvider(configService);
58
- expect(provider.options).toEqual({
59
- bootstrapAppConfig: {
60
- enableCompanyFeature: true,
61
- databaseMode: 'multi-tenant'
62
- },
63
- defaultDatabaseConfig: {
64
- type: 'mysql',
65
- host: 'db-host'
66
- },
67
- tenantDefaultDatabaseConfig: {
68
- type: 'mysql',
69
- host: 'tenant-host'
70
- },
71
- tenants: [
72
- {
73
- id: 'tenant-1',
74
- database: 'tenant_db'
75
- }
76
- ]
77
- });
78
- });
79
- it('builds parent options gracefully when config is not provided', ()=>{
80
- const configService = buildConfigService({
81
- options: {
82
- bootstrapAppConfig: undefined,
83
- config: undefined
84
- }
85
- });
86
- const provider = new EventManagerDataSourceProvider(configService);
87
- expect(provider.options).toEqual({
88
- bootstrapAppConfig: undefined,
89
- defaultDatabaseConfig: undefined,
90
- tenantDefaultDatabaseConfig: undefined,
91
- tenants: undefined
92
- });
93
- });
94
- });
95
- describe('getEnableCompanyFeatureForTenant', ()=>{
96
- it('returns the tenant override when explicitly true', ()=>{
97
- const configService = buildConfigService({
98
- isCompanyFeatureEnabled: false
99
- });
100
- const provider = new EventManagerDataSourceProvider(configService);
101
- const result = provider.getEnableCompanyFeatureForTenant({
102
- enableCompanyFeature: true
103
- });
104
- expect(result).toBe(true);
105
- });
106
- it('returns the tenant override when explicitly false', ()=>{
107
- const configService = buildConfigService({
108
- isCompanyFeatureEnabled: true
109
- });
110
- const provider = new EventManagerDataSourceProvider(configService);
111
- const result = provider.getEnableCompanyFeatureForTenant({
112
- enableCompanyFeature: false
113
- });
114
- expect(result).toBe(false);
115
- });
116
- it('falls back to the config service when tenant flag is undefined', ()=>{
117
- const configService = buildConfigService({
118
- isCompanyFeatureEnabled: true
119
- });
120
- const provider = new EventManagerDataSourceProvider(configService);
121
- const result = provider.getEnableCompanyFeatureForTenant({});
122
- expect(result).toBe(true);
123
- });
124
- it('falls back to the config service when no tenant is provided', ()=>{
125
- const configService = buildConfigService({
126
- isCompanyFeatureEnabled: false
127
- });
128
- const provider = new EventManagerDataSourceProvider(configService);
129
- const result = provider.getEnableCompanyFeatureForTenant(undefined);
130
- expect(result).toBe(false);
131
- });
132
- });
133
- describe('createDataSourceFromConfig', ()=>{
134
- it('loads core event-manager entities when the company feature is disabled', async ()=>{
135
- const configService = buildConfigService({
136
- isCompanyFeatureEnabled: false
137
- });
138
- const provider = new EventManagerDataSourceProvider(configService);
139
- const spy = jest.spyOn(MultiTenantDataSourceService.prototype, 'createDataSourceFromConfig').mockResolvedValue({
140
- isInitialized: true
141
- });
142
- const config = {
143
- type: 'mysql',
144
- host: 'localhost'
145
- };
146
- await provider.createDataSourceFromConfig(config);
147
- expect(spy).toHaveBeenCalledWith(config, expect.arrayContaining([
148
- Event,
149
- EventParticipant
150
- ]));
151
- expect(spy.mock.calls[0][1]).not.toContain(EventWithCompany);
152
- });
153
- it('loads company-scoped event-manager entities when the company feature is enabled', async ()=>{
154
- const configService = buildConfigService({
155
- isCompanyFeatureEnabled: true
156
- });
157
- const provider = new EventManagerDataSourceProvider(configService);
158
- const spy = jest.spyOn(MultiTenantDataSourceService.prototype, 'createDataSourceFromConfig').mockResolvedValue({
159
- isInitialized: true
160
- });
161
- const config = {
162
- type: 'mysql',
163
- host: 'localhost'
164
- };
165
- await provider.createDataSourceFromConfig(config);
166
- expect(spy).toHaveBeenCalledWith(config, expect.arrayContaining([
167
- EventWithCompany,
168
- EventParticipant
169
- ]));
170
- expect(spy.mock.calls[0][1]).not.toContain(Event);
171
- });
172
- it('uses the current tenant override to resolve entities when a request is present', async ()=>{
173
- const configService = buildConfigService({
174
- isCompanyFeatureEnabled: false
175
- });
176
- const provider = new EventManagerDataSourceProvider(configService);
177
- jest.spyOn(provider, 'getCurrentTenant').mockReturnValue({
178
- enableCompanyFeature: true
179
- });
180
- const spy = jest.spyOn(MultiTenantDataSourceService.prototype, 'createDataSourceFromConfig').mockResolvedValue({
181
- isInitialized: true
182
- });
183
- const config = {
184
- type: 'mysql',
185
- host: 'localhost'
186
- };
187
- await provider.createDataSourceFromConfig(config);
188
- expect(spy).toHaveBeenCalledWith(config, expect.arrayContaining([
189
- EventWithCompany,
190
- EventParticipant
191
- ]));
192
- });
193
- });
194
- });
@@ -1,225 +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 { EVENT_PARTICIPANT_MESSAGES } from '../config';
29
- import { Inject, Injectable, NotFoundException } from '@nestjs/common';
30
- import { IsNull } from 'typeorm';
31
- import { HybridCache } from '@flusys/nestjs-shared/classes';
32
- import { LogAction } from '@flusys/nestjs-shared/decorators';
33
- import { UtilsService } from '@flusys/nestjs-shared/modules';
34
- import { CreateEventOptions, ParticipantStatus, RecurrenceType } from '@flusys/nestjs-shared';
35
- import { EventManagerConfigService } from './event-manager-config.service';
36
- import { EventManagerDataSourceProvider } from './event-manager-datasource.provider';
37
- import { Event, EventWithCompany, EventParticipant } from '../entities';
38
- export class EventManagerHelperService {
39
- async getDataSource() {
40
- if (!this.dataSource) {
41
- this.dataSource = await this.dataSourceProvider.getDataSource();
42
- }
43
- return this.dataSource;
44
- }
45
- async getEventRepository() {
46
- const ds = await this.getDataSource();
47
- const EntityClass = this.configService.isCompanyFeatureEnabled() ? EventWithCompany : Event;
48
- return ds.getRepository(EntityClass);
49
- }
50
- async getParticipantRepository() {
51
- const ds = await this.getDataSource();
52
- return ds.getRepository(EventParticipant);
53
- }
54
- async createEvent(options) {
55
- const repo = await this.getEventRepository();
56
- const isAllDay = options.isAllDay ?? false;
57
- const entity = {
58
- title: options.title,
59
- description: options.description ?? null,
60
- eventDate: options.eventDate,
61
- startTime: isAllDay ? '00:00' : options.startTime,
62
- endTime: isAllDay ? '23:59' : options.endTime,
63
- isAllDay,
64
- recurrenceType: options.recurrenceType ?? RecurrenceType.NONE,
65
- recurrenceEndDate: options.recurrenceEndDate ?? null,
66
- weekDays: options.weekDays ?? null,
67
- color: options.color ?? this.configService.getDefaultColor(),
68
- meetingLink: options.meetingLink ?? null,
69
- isActive: true
70
- };
71
- if (this.configService.isCompanyFeatureEnabled() && options.companyId) {
72
- entity.companyId = options.companyId;
73
- }
74
- const saved = await repo.save(entity);
75
- await this.addEventParticipants(saved.id, options.participantIds ?? [], options.organizerId);
76
- await this.clearCache();
77
- return this.toEventResult(saved);
78
- }
79
- async updateParticipantStatus(participantId, status) {
80
- const participantRepo = await this.getParticipantRepository();
81
- const participant = await participantRepo.findOne({
82
- where: {
83
- id: participantId,
84
- deletedAt: IsNull()
85
- }
86
- });
87
- if (!participant) {
88
- throw new NotFoundException({
89
- message: 'Event participant not found',
90
- messageKey: EVENT_PARTICIPANT_MESSAGES.NOT_FOUND
91
- });
92
- }
93
- participant.status = status;
94
- await participantRepo.save(participant);
95
- }
96
- async getEventsForUser(userId, startDate, endDate, companyId) {
97
- const eventRepo = await this.getEventRepository();
98
- const participantRepo = await this.getParticipantRepository();
99
- const participantEvents = await participantRepo.createQueryBuilder('ep').select('ep.eventId').where('ep.userId = :userId', {
100
- userId
101
- }).andWhere('ep.deletedAt IS NULL').getRawMany();
102
- const eventIds = participantEvents.map((p)=>p.ep_event_id);
103
- if (eventIds.length === 0) {
104
- return [];
105
- }
106
- const query = eventRepo.createQueryBuilder('event').where('event.id IN (:...eventIds)', {
107
- eventIds
108
- }).andWhere('event.deletedAt IS NULL').andWhere('event.isActive = :isActive', {
109
- isActive: true
110
- }).andWhere('event.eventDate <= :endDate', {
111
- endDate
112
- }).andWhere('event.eventDate >= :startDate', {
113
- startDate
114
- });
115
- if (this.configService.isCompanyFeatureEnabled() && companyId) {
116
- query.andWhere('event.companyId = :companyId', {
117
- companyId
118
- });
119
- }
120
- const events = await query.getMany();
121
- return events.map((e)=>this.toEventResult(e));
122
- }
123
- async getEventById(eventId) {
124
- const repo = await this.getEventRepository();
125
- const event = await repo.findOne({
126
- where: {
127
- id: eventId,
128
- deletedAt: IsNull()
129
- }
130
- });
131
- return event ? this.toEventResult(event) : null;
132
- }
133
- async addEventParticipants(eventId, participantIds, organizerId) {
134
- if (!organizerId && participantIds.length === 0) return;
135
- const participantRepo = await this.getParticipantRepository();
136
- const allUserIds = new Set([
137
- ...organizerId ? [
138
- organizerId
139
- ] : [],
140
- ...participantIds
141
- ]);
142
- const participants = Array.from(allUserIds).map((userId)=>({
143
- eventId,
144
- userId,
145
- status: ParticipantStatus.PENDING,
146
- isOrganizer: userId === organizerId
147
- }));
148
- await participantRepo.save(participants);
149
- }
150
- toEventResult(event) {
151
- const eventExt = event;
152
- return {
153
- id: event.id,
154
- title: event.title,
155
- description: event.description,
156
- eventDate: event.eventDate,
157
- startTime: event.startTime,
158
- endTime: event.endTime,
159
- isAllDay: event.isAllDay,
160
- recurrenceType: event.recurrenceType,
161
- recurrenceEndDate: event.recurrenceEndDate,
162
- weekDays: event.weekDays,
163
- color: event.color,
164
- meetingLink: event.meetingLink ?? null,
165
- isActive: event.isActive,
166
- companyId: eventExt.companyId ?? null,
167
- createdAt: event.createdAt,
168
- updatedAt: event.updatedAt
169
- };
170
- }
171
- async clearCache() {
172
- await this.utilsService.clearCache(this.eventEntityName, this.cacheManager);
173
- }
174
- constructor(cacheManager, utilsService, configService, dataSourceProvider){
175
- _define_property(this, "cacheManager", void 0);
176
- _define_property(this, "utilsService", void 0);
177
- _define_property(this, "configService", void 0);
178
- _define_property(this, "dataSourceProvider", void 0);
179
- _define_property(this, "eventEntityName", void 0);
180
- _define_property(this, "dataSource", void 0);
181
- this.cacheManager = cacheManager;
182
- this.utilsService = utilsService;
183
- this.configService = configService;
184
- this.dataSourceProvider = dataSourceProvider;
185
- this.eventEntityName = 'event';
186
- this.dataSource = null;
187
- }
188
- }
189
- _ts_decorate([
190
- LogAction({
191
- action: 'event.create',
192
- module: 'event-manager'
193
- }),
194
- _ts_metadata("design:type", Function),
195
- _ts_metadata("design:paramtypes", [
196
- typeof CreateEventOptions === "undefined" ? Object : CreateEventOptions
197
- ]),
198
- _ts_metadata("design:returntype", Promise)
199
- ], EventManagerHelperService.prototype, "createEvent", null);
200
- _ts_decorate([
201
- LogAction({
202
- action: 'eventParticipant.updateStatus',
203
- module: 'event-manager'
204
- }),
205
- _ts_metadata("design:type", Function),
206
- _ts_metadata("design:paramtypes", [
207
- String,
208
- typeof ParticipantStatus === "undefined" ? Object : ParticipantStatus
209
- ]),
210
- _ts_metadata("design:returntype", Promise)
211
- ], EventManagerHelperService.prototype, "updateParticipantStatus", null);
212
- EventManagerHelperService = _ts_decorate([
213
- Injectable(),
214
- _ts_param(0, Inject('CACHE_INSTANCE')),
215
- _ts_param(1, Inject(UtilsService)),
216
- _ts_param(2, Inject(EventManagerConfigService)),
217
- _ts_param(3, Inject(EventManagerDataSourceProvider)),
218
- _ts_metadata("design:type", Function),
219
- _ts_metadata("design:paramtypes", [
220
- typeof HybridCache === "undefined" ? Object : HybridCache,
221
- typeof UtilsService === "undefined" ? Object : UtilsService,
222
- typeof EventManagerConfigService === "undefined" ? Object : EventManagerConfigService,
223
- typeof EventManagerDataSourceProvider === "undefined" ? Object : EventManagerDataSourceProvider
224
- ])
225
- ], EventManagerHelperService);