@flusys/nestjs-event-manager 7.1.0 → 8.0.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.
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,327 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- const _common = require("@nestjs/common");
6
- const _nestjsshared = require("@flusys/nestjs-shared");
7
- const _repositorymock = require("@test-utils/mocks/repository.mock");
8
- const _config = require("../config");
9
- const _entities = require("../entities");
10
- const _eventmanagerhelperservice = require("./event-manager-helper.service");
11
- function buildEvent(overrides = {}) {
12
- return {
13
- id: 'event-uuid-1',
14
- title: 'Sprint Planning',
15
- description: null,
16
- eventDate: '2026-04-03',
17
- startTime: '09:00',
18
- endTime: '10:00',
19
- isAllDay: false,
20
- recurrenceType: _nestjsshared.RecurrenceType.NONE,
21
- recurrenceEndDate: null,
22
- weekDays: null,
23
- color: '#3B82F6',
24
- meetingLink: null,
25
- isActive: true,
26
- createdAt: new Date('2026-01-01T00:00:00Z'),
27
- updatedAt: new Date('2026-01-01T00:00:00Z'),
28
- deletedAt: null,
29
- createdById: null,
30
- updatedById: null,
31
- deletedById: null,
32
- ...overrides
33
- };
34
- }
35
- function buildParticipant(overrides = {}) {
36
- return {
37
- id: 'participant-uuid-1',
38
- eventId: 'event-uuid-1',
39
- userId: 'user-uuid-1',
40
- status: _nestjsshared.ParticipantStatus.PENDING,
41
- isOrganizer: false,
42
- createdAt: new Date('2026-01-01T00:00:00Z'),
43
- updatedAt: new Date('2026-01-01T00:00:00Z'),
44
- deletedAt: null,
45
- createdById: null,
46
- updatedById: null,
47
- deletedById: null,
48
- ...overrides
49
- };
50
- }
51
- describe('EventManagerHelperService', ()=>{
52
- let service;
53
- let mockEventRepo;
54
- let mockParticipantRepo;
55
- let mockConfigService;
56
- let mockDataSourceProvider;
57
- let mockUtilsService;
58
- // `getRawMany` isn't part of the shared MockQueryBuilder — the participant queries in this
59
- // service use `.getRawMany()`, so we augment the shared mock query builder instances here.
60
- let mockEventQb;
61
- let mockParticipantQb;
62
- beforeEach(()=>{
63
- mockEventRepo = (0, _repositorymock.createMockRepository)();
64
- mockParticipantRepo = (0, _repositorymock.createMockRepository)();
65
- mockEventQb = mockEventRepo.createQueryBuilder();
66
- mockEventQb.getRawMany = jest.fn();
67
- mockParticipantQb = mockParticipantRepo.createQueryBuilder();
68
- mockParticipantQb.getRawMany = jest.fn();
69
- mockConfigService = {
70
- isCompanyFeatureEnabled: jest.fn().mockReturnValue(false),
71
- getDefaultColor: jest.fn().mockReturnValue('#3B82F6')
72
- };
73
- const fakeDataSource = {
74
- getRepository: jest.fn((entity)=>entity === _entities.EventParticipant ? mockParticipantRepo : mockEventRepo)
75
- };
76
- mockDataSourceProvider = {
77
- getDataSource: jest.fn().mockResolvedValue(fakeDataSource)
78
- };
79
- mockUtilsService = {
80
- clearCache: jest.fn()
81
- };
82
- service = new _eventmanagerhelperservice.EventManagerHelperService({}, mockUtilsService, mockConfigService, mockDataSourceProvider);
83
- });
84
- describe('createEvent', ()=>{
85
- it('creates a timed event with the given fields and clears the cache', async ()=>{
86
- const saved = buildEvent();
87
- mockEventRepo.save.mockResolvedValue(saved);
88
- mockParticipantRepo.save.mockResolvedValue([]);
89
- const result = await service.createEvent({
90
- title: 'Sprint Planning',
91
- eventDate: '2026-04-03',
92
- startTime: '09:00',
93
- endTime: '10:00'
94
- });
95
- expect(mockEventRepo.save).toHaveBeenCalledWith(expect.objectContaining({
96
- title: 'Sprint Planning',
97
- startTime: '09:00',
98
- endTime: '10:00',
99
- isAllDay: false,
100
- recurrenceType: _nestjsshared.RecurrenceType.NONE,
101
- color: '#3B82F6'
102
- }));
103
- expect(mockUtilsService.clearCache).toHaveBeenCalledWith('event', {});
104
- expect(result.id).toBe(saved.id);
105
- expect(result.companyId).toBeNull();
106
- });
107
- it('forces symbolic 00:00 / 23:59 markers for all-day events regardless of supplied times', async ()=>{
108
- const saved = buildEvent({
109
- isAllDay: true,
110
- startTime: '00:00',
111
- endTime: '23:59'
112
- });
113
- mockEventRepo.save.mockResolvedValue(saved);
114
- await service.createEvent({
115
- title: 'Company Holiday',
116
- eventDate: '2026-12-25',
117
- startTime: '09:00',
118
- endTime: '17:00',
119
- isAllDay: true
120
- });
121
- expect(mockEventRepo.save).toHaveBeenCalledWith(expect.objectContaining({
122
- isAllDay: true,
123
- startTime: '00:00',
124
- endTime: '23:59'
125
- }));
126
- });
127
- it('attaches companyId only when the company feature is enabled and a companyId is supplied', async ()=>{
128
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(true);
129
- const saved = buildEvent();
130
- mockEventRepo.save.mockResolvedValue(saved);
131
- await service.createEvent({
132
- title: 'Sprint Planning',
133
- eventDate: '2026-04-03',
134
- startTime: '09:00',
135
- endTime: '10:00',
136
- companyId: 'company-uuid-1'
137
- });
138
- expect(mockEventRepo.save).toHaveBeenCalledWith(expect.objectContaining({
139
- companyId: 'company-uuid-1'
140
- }));
141
- });
142
- it('does not attach companyId when the company feature is disabled, even if supplied', async ()=>{
143
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(false);
144
- const saved = buildEvent();
145
- mockEventRepo.save.mockResolvedValue(saved);
146
- await service.createEvent({
147
- title: 'Sprint Planning',
148
- eventDate: '2026-04-03',
149
- startTime: '09:00',
150
- endTime: '10:00',
151
- companyId: 'company-uuid-1'
152
- });
153
- const savedArg = mockEventRepo.save.mock.calls[0][0];
154
- expect(savedArg).not.toHaveProperty('companyId');
155
- });
156
- it('adds the organizer and all participants with PENDING status, de-duplicated', async ()=>{
157
- const saved = buildEvent();
158
- mockEventRepo.save.mockResolvedValue(saved);
159
- mockParticipantRepo.save.mockResolvedValue([]);
160
- await service.createEvent({
161
- title: 'Sprint Planning',
162
- eventDate: '2026-04-03',
163
- startTime: '09:00',
164
- endTime: '10:00',
165
- organizerId: 'organizer-uuid-1',
166
- participantIds: [
167
- 'organizer-uuid-1',
168
- 'participant-uuid-2'
169
- ]
170
- });
171
- const savedParticipants = mockParticipantRepo.save.mock.calls[0][0];
172
- expect(savedParticipants).toHaveLength(2);
173
- expect(savedParticipants).toEqual(expect.arrayContaining([
174
- expect.objectContaining({
175
- userId: 'organizer-uuid-1',
176
- isOrganizer: true,
177
- status: _nestjsshared.ParticipantStatus.PENDING
178
- }),
179
- expect.objectContaining({
180
- userId: 'participant-uuid-2',
181
- isOrganizer: false,
182
- status: _nestjsshared.ParticipantStatus.PENDING
183
- })
184
- ]));
185
- });
186
- it('skips participant creation entirely when no organizer or participants are given', async ()=>{
187
- const saved = buildEvent();
188
- mockEventRepo.save.mockResolvedValue(saved);
189
- await service.createEvent({
190
- title: 'Sprint Planning',
191
- eventDate: '2026-04-03',
192
- startTime: '09:00',
193
- endTime: '10:00'
194
- });
195
- expect(mockParticipantRepo.save).not.toHaveBeenCalled();
196
- });
197
- });
198
- describe('updateParticipantStatus', ()=>{
199
- it('updates the status of an existing participant', async ()=>{
200
- const participant = buildParticipant({
201
- status: _nestjsshared.ParticipantStatus.PENDING
202
- });
203
- mockParticipantRepo.findOne.mockResolvedValue(participant);
204
- mockParticipantRepo.save.mockResolvedValue({
205
- ...participant,
206
- status: _nestjsshared.ParticipantStatus.ACCEPTED
207
- });
208
- await service.updateParticipantStatus('participant-uuid-1', _nestjsshared.ParticipantStatus.ACCEPTED);
209
- expect(mockParticipantRepo.save).toHaveBeenCalledWith(expect.objectContaining({
210
- status: _nestjsshared.ParticipantStatus.ACCEPTED
211
- }));
212
- });
213
- it('throws NotFoundException with the correct messageKey when the participant does not exist', async ()=>{
214
- mockParticipantRepo.findOne.mockResolvedValue(null);
215
- await expect(service.updateParticipantStatus('missing-uuid', _nestjsshared.ParticipantStatus.ACCEPTED)).rejects.toMatchObject({
216
- response: expect.objectContaining({
217
- messageKey: _config.EVENT_PARTICIPANT_MESSAGES.NOT_FOUND
218
- })
219
- });
220
- await expect(service.updateParticipantStatus('missing-uuid', _nestjsshared.ParticipantStatus.ACCEPTED)).rejects.toBeInstanceOf(_common.NotFoundException);
221
- });
222
- });
223
- describe('getEventsForUser', ()=>{
224
- it('returns an empty list without querying events when the user has no participant rows', async ()=>{
225
- mockParticipantQb.getRawMany.mockResolvedValue([]);
226
- const result = await service.getEventsForUser('user-uuid-1', '2026-04-01', '2026-04-30');
227
- expect(result).toEqual([]);
228
- expect(mockEventQb.getMany).not.toHaveBeenCalled();
229
- expect(mockEventQb.where).not.toHaveBeenCalled();
230
- });
231
- it('queries events scoped to the participant event ids and date range', async ()=>{
232
- mockParticipantQb.getRawMany.mockResolvedValue([
233
- {
234
- ep_event_id: 'event-uuid-1'
235
- }
236
- ]);
237
- const events = [
238
- buildEvent()
239
- ];
240
- mockEventQb.getMany.mockResolvedValue(events);
241
- const result = await service.getEventsForUser('user-uuid-1', '2026-04-01', '2026-04-30');
242
- const eventQb = mockEventQb;
243
- expect(eventQb.where).toHaveBeenCalledWith('event.id IN (:...eventIds)', {
244
- eventIds: [
245
- 'event-uuid-1'
246
- ]
247
- });
248
- expect(eventQb.andWhere).toHaveBeenCalledWith('event.eventDate <= :endDate', {
249
- endDate: '2026-04-30'
250
- });
251
- expect(eventQb.andWhere).toHaveBeenCalledWith('event.eventDate >= :startDate', {
252
- startDate: '2026-04-01'
253
- });
254
- expect(result).toHaveLength(1);
255
- expect(result[0].id).toBe('event-uuid-1');
256
- });
257
- it('handles a zero-length range (startDate === endDate)', async ()=>{
258
- mockParticipantQb.getRawMany.mockResolvedValue([
259
- {
260
- ep_event_id: 'event-uuid-1'
261
- }
262
- ]);
263
- mockEventQb.getMany.mockResolvedValue([
264
- buildEvent()
265
- ]);
266
- const result = await service.getEventsForUser('user-uuid-1', '2026-04-03', '2026-04-03');
267
- const eventQb = mockEventQb;
268
- expect(eventQb.andWhere).toHaveBeenCalledWith('event.eventDate <= :endDate', {
269
- endDate: '2026-04-03'
270
- });
271
- expect(eventQb.andWhere).toHaveBeenCalledWith('event.eventDate >= :startDate', {
272
- startDate: '2026-04-03'
273
- });
274
- expect(result).toHaveLength(1);
275
- });
276
- it('scopes the query to the company when the company feature is enabled and a companyId is given', async ()=>{
277
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(true);
278
- mockParticipantQb.getRawMany.mockResolvedValue([
279
- {
280
- ep_event_id: 'event-uuid-1'
281
- }
282
- ]);
283
- mockEventQb.getMany.mockResolvedValue([
284
- buildEvent()
285
- ]);
286
- await service.getEventsForUser('user-uuid-1', '2026-04-01', '2026-04-30', 'company-uuid-1');
287
- const eventQb = mockEventQb;
288
- expect(eventQb.andWhere).toHaveBeenCalledWith('event.companyId = :companyId', {
289
- companyId: 'company-uuid-1'
290
- });
291
- });
292
- it('does not scope the query to the company when the company feature is disabled', async ()=>{
293
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(false);
294
- mockParticipantQb.getRawMany.mockResolvedValue([
295
- {
296
- ep_event_id: 'event-uuid-1'
297
- }
298
- ]);
299
- mockEventQb.getMany.mockResolvedValue([
300
- buildEvent()
301
- ]);
302
- await service.getEventsForUser('user-uuid-1', '2026-04-01', '2026-04-30', 'company-uuid-1');
303
- const eventQb = mockEventQb;
304
- const companyCalls = eventQb.andWhere.mock.calls.filter((call)=>call[0] === 'event.companyId = :companyId');
305
- expect(companyCalls).toHaveLength(0);
306
- });
307
- it('requests the correct entity for the company feature toggle', async ()=>{
308
- mockConfigService.isCompanyFeatureEnabled.mockReturnValue(true);
309
- mockParticipantQb.getRawMany.mockResolvedValue([]);
310
- await service.getEventsForUser('user-uuid-1', '2026-04-01', '2026-04-30');
311
- const fakeDataSource = await mockDataSourceProvider.getDataSource();
312
- expect(fakeDataSource.getRepository).toHaveBeenCalledWith(_entities.EventWithCompany);
313
- });
314
- });
315
- describe('getEventById', ()=>{
316
- it('returns the mapped event when found', async ()=>{
317
- mockEventRepo.findOne.mockResolvedValue(buildEvent());
318
- const result = await service.getEventById('event-uuid-1');
319
- expect(result?.id).toBe('event-uuid-1');
320
- });
321
- it('returns null when the event does not exist', async ()=>{
322
- mockEventRepo.findOne.mockResolvedValue(null);
323
- const result = await service.getEventById('missing-uuid');
324
- expect(result).toBeNull();
325
- });
326
- });
327
- });