@flusys/nestjs-email 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 (159) hide show
  1. package/config/index.d.ts +3 -3
  2. package/controllers/email-config.controller.d.ts +2 -2
  3. package/controllers/email-send.controller.d.ts +3 -3
  4. package/controllers/email-template.controller.d.ts +4 -4
  5. package/controllers/index.d.ts +3 -3
  6. package/docs/email-swagger.config.d.ts +2 -2
  7. package/docs/index.d.ts +1 -1
  8. package/dtos/email-config.dto.d.ts +1 -1
  9. package/dtos/email-send.dto.d.ts +1 -1
  10. package/dtos/index.d.ts +3 -3
  11. package/entities/email-config-with-company.entity.d.ts +1 -1
  12. package/entities/email-template-with-company.entity.d.ts +1 -1
  13. package/entities/index.d.ts +10 -10
  14. package/enums/index.d.ts +1 -1
  15. package/fesm/261.js +799 -0
  16. package/fesm/493.js +1723 -0
  17. package/fesm/chunks/99.js +12 -0
  18. package/fesm/config/index.js +104 -3
  19. package/fesm/controllers/index.js +396 -3
  20. package/fesm/docs/index.js +134 -1
  21. package/fesm/dtos/index.js +22 -3
  22. package/fesm/entities/index.js +409 -13
  23. package/fesm/enums/index.js +37 -1
  24. package/fesm/index.js +762 -10
  25. package/fesm/interfaces/index.js +18 -4
  26. package/fesm/modules/index.js +541 -1
  27. package/fesm/providers/index.js +523 -5
  28. package/fesm/runtime.js +134 -0
  29. package/fesm/services/index.js +17 -5
  30. package/index.d.ts +10 -10
  31. package/interfaces/email-config.interface.d.ts +2 -2
  32. package/interfaces/email-module-options.interface.d.ts +3 -3
  33. package/interfaces/email-template.interface.d.ts +1 -1
  34. package/interfaces/index.d.ts +4 -4
  35. package/modules/email.module.d.ts +2 -2
  36. package/modules/index.d.ts +1 -1
  37. package/package.json +27 -38
  38. package/providers/email-factory.service.d.ts +2 -2
  39. package/providers/email-provider.registry.d.ts +2 -2
  40. package/providers/index.d.ts +5 -5
  41. package/providers/mailgun-provider.d.ts +1 -1
  42. package/providers/sendgrid-provider.d.ts +1 -1
  43. package/providers/smtp-provider.d.ts +1 -1
  44. package/services/email-config.service.d.ts +3 -3
  45. package/services/email-datasource.provider.d.ts +3 -3
  46. package/services/email-provider-config.service.d.ts +7 -7
  47. package/services/email-send.service.d.ts +7 -7
  48. package/services/email-template.service.d.ts +6 -6
  49. package/services/index.d.ts +5 -5
  50. package/utils/index.d.ts +1 -1
  51. package/cjs/config/email.constants.js +0 -22
  52. package/cjs/config/event-actions.js +0 -34
  53. package/cjs/config/index.js +0 -20
  54. package/cjs/config/message-keys.js +0 -39
  55. package/cjs/controllers/email-config.controller.js +0 -111
  56. package/cjs/controllers/email-config.controller.spec.js +0 -85
  57. package/cjs/controllers/email-send.controller.js +0 -128
  58. package/cjs/controllers/email-send.controller.spec.js +0 -139
  59. package/cjs/controllers/email-template.controller.js +0 -142
  60. package/cjs/controllers/email-template.controller.spec.js +0 -89
  61. package/cjs/controllers/index.js +0 -20
  62. package/cjs/docs/email-swagger.config.js +0 -116
  63. package/cjs/docs/email-swagger.config.spec.js +0 -62
  64. package/cjs/docs/index.js +0 -11
  65. package/cjs/dtos/email-config.dto.js +0 -212
  66. package/cjs/dtos/email-send.dto.js +0 -354
  67. package/cjs/dtos/email-template.dto.js +0 -252
  68. package/cjs/dtos/index.js +0 -20
  69. package/cjs/entities/email-config-with-company.entity.js +0 -63
  70. package/cjs/entities/email-config.entity.js +0 -114
  71. package/cjs/entities/email-template-with-company.entity.js +0 -65
  72. package/cjs/entities/email-template.entity.js +0 -136
  73. package/cjs/entities/index.js +0 -56
  74. package/cjs/entities/index.spec.js +0 -18
  75. package/cjs/enums/email-provider-type.enum.js +0 -18
  76. package/cjs/enums/index.js +0 -18
  77. package/cjs/index.js +0 -28
  78. package/cjs/interfaces/email-config.interface.js +0 -4
  79. package/cjs/interfaces/email-module-options.interface.js +0 -4
  80. package/cjs/interfaces/email-provider.interface.js +0 -4
  81. package/cjs/interfaces/email-template.interface.js +0 -4
  82. package/cjs/interfaces/index.js +0 -21
  83. package/cjs/modules/email.module.js +0 -122
  84. package/cjs/modules/email.module.spec.js +0 -142
  85. package/cjs/modules/index.js +0 -18
  86. package/cjs/providers/email-factory.service.js +0 -113
  87. package/cjs/providers/email-factory.service.spec.js +0 -242
  88. package/cjs/providers/email-provider.registry.js +0 -41
  89. package/cjs/providers/email-provider.registry.spec.js +0 -58
  90. package/cjs/providers/index.js +0 -22
  91. package/cjs/providers/mailgun-provider.js +0 -119
  92. package/cjs/providers/mailgun-provider.spec.js +0 -244
  93. package/cjs/providers/sendgrid-provider.js +0 -129
  94. package/cjs/providers/sendgrid-provider.spec.js +0 -346
  95. package/cjs/providers/smtp-provider.js +0 -164
  96. package/cjs/providers/smtp-provider.spec.js +0 -327
  97. package/cjs/services/email-config.service.js +0 -71
  98. package/cjs/services/email-config.service.spec.js +0 -69
  99. package/cjs/services/email-datasource.provider.js +0 -84
  100. package/cjs/services/email-datasource.provider.spec.js +0 -135
  101. package/cjs/services/email-provider-config.service.js +0 -159
  102. package/cjs/services/email-provider-config.service.spec.js +0 -269
  103. package/cjs/services/email-send.service.js +0 -315
  104. package/cjs/services/email-send.service.spec.js +0 -614
  105. package/cjs/services/email-template.service.js +0 -144
  106. package/cjs/services/email-template.service.spec.js +0 -261
  107. package/cjs/services/index.js +0 -22
  108. package/cjs/utils/email-templates.util.js +0 -64
  109. package/cjs/utils/email-templates.util.spec.js +0 -61
  110. package/cjs/utils/index.js +0 -18
  111. package/fesm/config/email.constants.js +0 -4
  112. package/fesm/config/event-actions.js +0 -13
  113. package/fesm/config/message-keys.js +0 -18
  114. package/fesm/controllers/email-config.controller.js +0 -101
  115. package/fesm/controllers/email-config.controller.spec.js +0 -81
  116. package/fesm/controllers/email-send.controller.js +0 -118
  117. package/fesm/controllers/email-send.controller.spec.js +0 -135
  118. package/fesm/controllers/email-template.controller.js +0 -132
  119. package/fesm/controllers/email-template.controller.spec.js +0 -85
  120. package/fesm/docs/email-swagger.config.js +0 -109
  121. package/fesm/docs/email-swagger.config.spec.js +0 -58
  122. package/fesm/dtos/email-config.dto.js +0 -191
  123. package/fesm/dtos/email-send.dto.js +0 -324
  124. package/fesm/dtos/email-template.dto.js +0 -231
  125. package/fesm/entities/email-config-with-company.entity.js +0 -53
  126. package/fesm/entities/email-config.entity.js +0 -104
  127. package/fesm/entities/email-template-with-company.entity.js +0 -55
  128. package/fesm/entities/email-template.entity.js +0 -126
  129. package/fesm/entities/index.spec.js +0 -14
  130. package/fesm/enums/email-provider-type.enum.js +0 -8
  131. package/fesm/interfaces/email-config.interface.js +0 -1
  132. package/fesm/interfaces/email-module-options.interface.js +0 -1
  133. package/fesm/interfaces/email-provider.interface.js +0 -1
  134. package/fesm/interfaces/email-template.interface.js +0 -1
  135. package/fesm/modules/email.module.js +0 -112
  136. package/fesm/modules/email.module.spec.js +0 -138
  137. package/fesm/providers/email-factory.service.js +0 -103
  138. package/fesm/providers/email-factory.service.spec.js +0 -238
  139. package/fesm/providers/email-provider.registry.js +0 -31
  140. package/fesm/providers/email-provider.registry.spec.js +0 -54
  141. package/fesm/providers/mailgun-provider.js +0 -109
  142. package/fesm/providers/mailgun-provider.spec.js +0 -240
  143. package/fesm/providers/sendgrid-provider.js +0 -119
  144. package/fesm/providers/sendgrid-provider.spec.js +0 -342
  145. package/fesm/providers/smtp-provider.js +0 -113
  146. package/fesm/providers/smtp-provider.spec.js +0 -282
  147. package/fesm/services/email-config.service.js +0 -61
  148. package/fesm/services/email-config.service.spec.js +0 -65
  149. package/fesm/services/email-datasource.provider.js +0 -74
  150. package/fesm/services/email-datasource.provider.spec.js +0 -131
  151. package/fesm/services/email-provider-config.service.js +0 -149
  152. package/fesm/services/email-provider-config.service.spec.js +0 -265
  153. package/fesm/services/email-send.service.js +0 -305
  154. package/fesm/services/email-send.service.spec.js +0 -610
  155. package/fesm/services/email-template.service.js +0 -134
  156. package/fesm/services/email-template.service.spec.js +0 -257
  157. package/fesm/utils/email-templates.util.js +0 -47
  158. package/fesm/utils/email-templates.util.spec.js +0 -57
  159. package/fesm/utils/index.js +0 -1
@@ -1,101 +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 { createApiController, EMAIL_CONFIG_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
- import { Controller, Inject } from '@nestjs/common';
30
- import { ApiTags } from '@nestjs/swagger';
31
- import { CreateEmailConfigDto, EmailConfigResponseDto, UpdateEmailConfigDto } from '../dtos';
32
- import { EmailProviderConfigService } from '../services';
33
- export class EmailConfigController extends createApiController(CreateEmailConfigDto, UpdateEmailConfigDto, EmailConfigResponseDto, {
34
- entityName: 'email.config',
35
- security: {
36
- insert: {
37
- level: 'permission',
38
- permissions: [
39
- EMAIL_CONFIG_PERMISSIONS.CREATE
40
- ]
41
- },
42
- insertMany: {
43
- level: 'permission',
44
- permissions: [
45
- EMAIL_CONFIG_PERMISSIONS.CREATE
46
- ]
47
- },
48
- getById: {
49
- level: 'permission',
50
- permissions: [
51
- EMAIL_CONFIG_PERMISSIONS.READ
52
- ]
53
- },
54
- getAll: {
55
- level: 'permission',
56
- permissions: [
57
- EMAIL_CONFIG_PERMISSIONS.READ
58
- ]
59
- },
60
- update: {
61
- level: 'permission',
62
- permissions: [
63
- EMAIL_CONFIG_PERMISSIONS.UPDATE
64
- ]
65
- },
66
- updateMany: {
67
- level: 'permission',
68
- permissions: [
69
- EMAIL_CONFIG_PERMISSIONS.UPDATE
70
- ]
71
- },
72
- delete: {
73
- level: 'permission',
74
- permissions: [
75
- EMAIL_CONFIG_PERMISSIONS.DELETE
76
- ]
77
- }
78
- },
79
- enabledEndpoints: [
80
- 'insert',
81
- 'insertMany',
82
- 'getById',
83
- 'getAll',
84
- 'update',
85
- 'updateMany',
86
- 'delete'
87
- ]
88
- }) {
89
- constructor(emailConfigService){
90
- super(emailConfigService), _define_property(this, "emailConfigService", void 0), this.emailConfigService = emailConfigService;
91
- }
92
- }
93
- EmailConfigController = _ts_decorate([
94
- ApiTags('Email Config'),
95
- Controller('email/email-config'),
96
- _ts_param(0, Inject(EmailProviderConfigService)),
97
- _ts_metadata("design:type", Function),
98
- _ts_metadata("design:paramtypes", [
99
- typeof EmailProviderConfigService === "undefined" ? Object : EmailProviderConfigService
100
- ])
101
- ], EmailConfigController);
@@ -1,81 +0,0 @@
1
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
2
- import { EmailConfigController } from './email-config.controller';
3
- function buildEmailConfig(overrides = {}) {
4
- return {
5
- id: 'email-config-1',
6
- provider: 'smtp',
7
- isActive: true,
8
- isDefault: true,
9
- readOnly: false,
10
- createdAt: new Date(),
11
- updatedAt: new Date(),
12
- ...overrides
13
- };
14
- }
15
- describe('EmailConfigController', ()=>{
16
- let controller;
17
- let mockEmailConfigService;
18
- beforeEach(()=>{
19
- mockEmailConfigService = {
20
- insert: jest.fn(),
21
- findById: jest.fn(),
22
- getAll: jest.fn(),
23
- update: jest.fn(),
24
- delete: jest.fn()
25
- };
26
- controller = new EmailConfigController(mockEmailConfigService);
27
- });
28
- it('wires the injected service onto the generated controller base', ()=>{
29
- expect(controller.emailConfigService).toBe(mockEmailConfigService);
30
- expect(controller.service).toBe(mockEmailConfigService);
31
- });
32
- describe('insert', ()=>{
33
- it('creates an email config and returns the mapped response', async ()=>{
34
- const user = buildMockUser();
35
- mockEmailConfigService.insert.mockResolvedValue(buildEmailConfig());
36
- const result = await controller.insert({
37
- provider: 'smtp'
38
- }, user);
39
- expect(mockEmailConfigService.insert).toHaveBeenCalledWith({
40
- provider: 'smtp'
41
- }, user);
42
- expect(result.success).toBe(true);
43
- expect(result.data).toEqual(expect.objectContaining({
44
- id: 'email-config-1'
45
- }));
46
- });
47
- });
48
- describe('getAll', ()=>{
49
- it('paginates email configs and maps the response list', async ()=>{
50
- mockEmailConfigService.getAll.mockResolvedValue({
51
- data: [
52
- buildEmailConfig()
53
- ],
54
- total: 1
55
- });
56
- const result = await controller.getAll({}, buildMockUser(), '');
57
- expect(mockEmailConfigService.getAll).toHaveBeenCalledWith('', {}, buildMockUser());
58
- expect(result.data).toHaveLength(1);
59
- });
60
- });
61
- describe('delete', ()=>{
62
- it('delegates soft-delete to the service', async ()=>{
63
- mockEmailConfigService.delete.mockResolvedValue({
64
- count: 1
65
- });
66
- const result = await controller.delete({
67
- id: [
68
- 'email-config-1'
69
- ],
70
- type: 'delete'
71
- }, buildMockUser());
72
- expect(mockEmailConfigService.delete).toHaveBeenCalledWith({
73
- id: [
74
- 'email-config-1'
75
- ],
76
- type: 'delete'
77
- }, buildMockUser());
78
- expect(result.success).toBe(true);
79
- });
80
- });
81
- });
@@ -1,118 +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 { CurrentUser } from '@flusys/nestjs-shared/decorators';
29
- import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
30
- import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
31
- import { Body, Controller, Inject, Post, UseGuards } from '@nestjs/common';
32
- import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
33
- import { EMAIL_SEND_MESSAGES } from '../config';
34
- import { SendEmailDto, SendTemplateEmailDto, TestEmailDto } from '../dtos';
35
- import { EmailSendService } from '../services';
36
- export class EmailSendController {
37
- async sendEmail(dto, user) {
38
- const result = await this.emailSendService.sendEmail(dto, user);
39
- return this.toResponse(result, 'Email');
40
- }
41
- async sendTemplateEmail(dto, user) {
42
- const result = await this.emailSendService.sendTemplateEmail(dto, user);
43
- return this.toResponse(result, 'Template email');
44
- }
45
- async sendTestEmail(dto, user) {
46
- const result = await this.emailSendService.sendTestEmail(dto.emailConfigId, dto.recipient, user);
47
- return this.toResponse(result, 'Test email');
48
- }
49
- toResponse(result, label) {
50
- return {
51
- success: result.success,
52
- message: result.success ? `${label} sent successfully` : `Failed to send ${label.toLowerCase()}`,
53
- messageKey: result.success ? EMAIL_SEND_MESSAGES.SUCCESS : EMAIL_SEND_MESSAGES.FAILED,
54
- data: {
55
- success: result.success,
56
- messageId: result.messageId,
57
- error: result.error
58
- }
59
- };
60
- }
61
- constructor(emailSendService){
62
- _define_property(this, "emailSendService", void 0);
63
- this.emailSendService = emailSendService;
64
- }
65
- }
66
- _ts_decorate([
67
- Post('direct'),
68
- ApiOperation({
69
- summary: 'Send email directly with custom content'
70
- }),
71
- _ts_param(0, Body()),
72
- _ts_param(1, CurrentUser()),
73
- _ts_metadata("design:type", Function),
74
- _ts_metadata("design:paramtypes", [
75
- typeof SendEmailDto === "undefined" ? Object : SendEmailDto,
76
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
77
- ]),
78
- _ts_metadata("design:returntype", Promise)
79
- ], EmailSendController.prototype, "sendEmail", null);
80
- _ts_decorate([
81
- Post('template'),
82
- ApiOperation({
83
- summary: 'Send email using a template with variable interpolation'
84
- }),
85
- _ts_param(0, Body()),
86
- _ts_param(1, CurrentUser()),
87
- _ts_metadata("design:type", Function),
88
- _ts_metadata("design:paramtypes", [
89
- typeof SendTemplateEmailDto === "undefined" ? Object : SendTemplateEmailDto,
90
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
91
- ]),
92
- _ts_metadata("design:returntype", Promise)
93
- ], EmailSendController.prototype, "sendTemplateEmail", null);
94
- _ts_decorate([
95
- Post('test'),
96
- ApiOperation({
97
- summary: 'Send a test email to verify configuration'
98
- }),
99
- _ts_param(0, Body()),
100
- _ts_param(1, CurrentUser()),
101
- _ts_metadata("design:type", Function),
102
- _ts_metadata("design:paramtypes", [
103
- typeof TestEmailDto === "undefined" ? Object : TestEmailDto,
104
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
105
- ]),
106
- _ts_metadata("design:returntype", Promise)
107
- ], EmailSendController.prototype, "sendTestEmail", null);
108
- EmailSendController = _ts_decorate([
109
- ApiTags('Email Send'),
110
- ApiBearerAuth(),
111
- Controller('email/send'),
112
- UseGuards(JwtAuthGuard),
113
- _ts_param(0, Inject(EmailSendService)),
114
- _ts_metadata("design:type", Function),
115
- _ts_metadata("design:paramtypes", [
116
- typeof EmailSendService === "undefined" ? Object : EmailSendService
117
- ])
118
- ], EmailSendController);
@@ -1,135 +0,0 @@
1
- import { Test } from '@nestjs/testing';
2
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
3
- import { EmailSendController } from './email-send.controller';
4
- import { EmailSendService } from '../services';
5
- describe('EmailSendController', ()=>{
6
- let controller;
7
- let mockService;
8
- beforeEach(async ()=>{
9
- mockService = {
10
- sendEmail: jest.fn(),
11
- sendTemplateEmail: jest.fn(),
12
- sendTestEmail: jest.fn()
13
- };
14
- const module = await Test.createTestingModule({
15
- controllers: [
16
- EmailSendController
17
- ],
18
- providers: [
19
- {
20
- provide: EmailSendService,
21
- useValue: mockService
22
- }
23
- ]
24
- }).compile();
25
- controller = module.get(EmailSendController);
26
- });
27
- describe('sendEmail', ()=>{
28
- it('delegates to the service and returns a success response', async ()=>{
29
- mockService.sendEmail.mockResolvedValue({
30
- success: true,
31
- messageId: 'msg-1'
32
- });
33
- const dto = {
34
- to: 'a@example.com',
35
- subject: 'Hi',
36
- html: '<p/>'
37
- };
38
- const user = buildMockUser();
39
- const result = await controller.sendEmail(dto, user);
40
- expect(mockService.sendEmail).toHaveBeenCalledWith(dto, user);
41
- expect(result).toEqual({
42
- success: true,
43
- message: 'Email sent successfully',
44
- messageKey: 'email.send.success',
45
- data: {
46
- success: true,
47
- messageId: 'msg-1',
48
- error: undefined
49
- }
50
- });
51
- });
52
- it('returns a failure response with the FAILED messageKey when the send fails', async ()=>{
53
- mockService.sendEmail.mockResolvedValue({
54
- success: false,
55
- error: 'SMTP down'
56
- });
57
- const result = await controller.sendEmail({
58
- to: 'a@example.com',
59
- subject: 'Hi',
60
- html: '<p/>'
61
- }, buildMockUser());
62
- expect(result).toEqual({
63
- success: false,
64
- message: 'Failed to send email',
65
- messageKey: 'email.send.failed',
66
- data: {
67
- success: false,
68
- messageId: undefined,
69
- error: 'SMTP down'
70
- }
71
- });
72
- });
73
- });
74
- describe('sendTemplateEmail', ()=>{
75
- it('delegates to the service and returns a success response', async ()=>{
76
- mockService.sendTemplateEmail.mockResolvedValue({
77
- success: true,
78
- messageId: 'msg-2'
79
- });
80
- const dto = {
81
- to: 'a@example.com',
82
- templateSlug: 'welcome'
83
- };
84
- const user = buildMockUser();
85
- const result = await controller.sendTemplateEmail(dto, user);
86
- expect(mockService.sendTemplateEmail).toHaveBeenCalledWith(dto, user);
87
- expect(result.success).toBe(true);
88
- expect(result.messageKey).toBe('email.send.success');
89
- expect(result.message).toBe('Template email sent successfully');
90
- });
91
- it('returns a failure response when the template send fails', async ()=>{
92
- mockService.sendTemplateEmail.mockResolvedValue({
93
- success: false,
94
- error: 'Template error'
95
- });
96
- const result = await controller.sendTemplateEmail({
97
- to: 'a@example.com',
98
- templateSlug: 'welcome'
99
- }, buildMockUser());
100
- expect(result.success).toBe(false);
101
- expect(result.messageKey).toBe('email.send.failed');
102
- expect(result.message).toBe('Failed to send template email');
103
- });
104
- });
105
- describe('sendTestEmail', ()=>{
106
- it('delegates to the service with the emailConfigId and recipient from the dto', async ()=>{
107
- mockService.sendTestEmail.mockResolvedValue({
108
- success: true,
109
- messageId: 'msg-3'
110
- });
111
- const dto = {
112
- emailConfigId: 'config-1',
113
- recipient: 'a@example.com'
114
- };
115
- const user = buildMockUser();
116
- const result = await controller.sendTestEmail(dto, user);
117
- expect(mockService.sendTestEmail).toHaveBeenCalledWith('config-1', 'a@example.com', user);
118
- expect(result.success).toBe(true);
119
- expect(result.message).toBe('Test email sent successfully');
120
- });
121
- it('returns a failure response when the test send fails', async ()=>{
122
- mockService.sendTestEmail.mockResolvedValue({
123
- success: false,
124
- error: 'Bad config'
125
- });
126
- const result = await controller.sendTestEmail({
127
- emailConfigId: 'config-1',
128
- recipient: 'a@example.com'
129
- }, buildMockUser());
130
- expect(result.success).toBe(false);
131
- expect(result.message).toBe('Failed to send test email');
132
- expect(result.messageKey).toBe('email.send.failed');
133
- });
134
- });
135
- });
@@ -1,132 +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 { createApiController, EMAIL_TEMPLATE_PERMISSIONS } from '@flusys/nestjs-shared/classes';
29
- import { CurrentUser, RequirePermission } from '@flusys/nestjs-shared/decorators';
30
- import { JwtAuthGuard, PermissionGuard } from '@flusys/nestjs-shared/guards';
31
- import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
32
- import { Body, Controller, Inject, NotFoundException, Post, UseGuards } from '@nestjs/common';
33
- import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
34
- import { EMAIL_TEMPLATE_MESSAGES } from '../config';
35
- import { CreateEmailTemplateDto, EmailTemplateResponseDto, UpdateEmailTemplateDto } from '../dtos';
36
- import { EmailTemplateService } from '../services';
37
- export class EmailTemplateController extends createApiController(CreateEmailTemplateDto, UpdateEmailTemplateDto, EmailTemplateResponseDto, {
38
- entityName: 'email.template',
39
- security: {
40
- insert: {
41
- level: 'permission',
42
- permissions: [
43
- EMAIL_TEMPLATE_PERMISSIONS.CREATE
44
- ]
45
- },
46
- insertMany: {
47
- level: 'permission',
48
- permissions: [
49
- EMAIL_TEMPLATE_PERMISSIONS.CREATE
50
- ]
51
- },
52
- getById: {
53
- level: 'permission',
54
- permissions: [
55
- EMAIL_TEMPLATE_PERMISSIONS.READ
56
- ]
57
- },
58
- getAll: {
59
- level: 'permission',
60
- permissions: [
61
- EMAIL_TEMPLATE_PERMISSIONS.READ
62
- ]
63
- },
64
- update: {
65
- level: 'permission',
66
- permissions: [
67
- EMAIL_TEMPLATE_PERMISSIONS.UPDATE
68
- ]
69
- },
70
- updateMany: {
71
- level: 'permission',
72
- permissions: [
73
- EMAIL_TEMPLATE_PERMISSIONS.UPDATE
74
- ]
75
- },
76
- delete: {
77
- level: 'permission',
78
- permissions: [
79
- EMAIL_TEMPLATE_PERMISSIONS.DELETE
80
- ]
81
- }
82
- }
83
- }) {
84
- async getBySlug(body, user) {
85
- const data = await this.emailTemplateService.findBySlug(body.slug, user);
86
- if (!data) {
87
- throw new NotFoundException({
88
- message: 'Email template not found',
89
- messageKey: EMAIL_TEMPLATE_MESSAGES.NOT_FOUND
90
- });
91
- }
92
- return {
93
- success: true,
94
- message: 'Template retrieved',
95
- messageKey: EMAIL_TEMPLATE_MESSAGES.GET_SUCCESS,
96
- data
97
- };
98
- }
99
- constructor(emailTemplateService){
100
- super(emailTemplateService), _define_property(this, "emailTemplateService", void 0), this.emailTemplateService = emailTemplateService;
101
- }
102
- }
103
- _ts_decorate([
104
- Post('get-by-slug'),
105
- UseGuards(JwtAuthGuard, PermissionGuard),
106
- ApiBearerAuth(),
107
- RequirePermission(EMAIL_TEMPLATE_PERMISSIONS.READ),
108
- ApiOperation({
109
- summary: 'Get email template by slug'
110
- }),
111
- ApiResponse({
112
- status: 200,
113
- type: EmailTemplateResponseDto
114
- }),
115
- _ts_param(0, Body()),
116
- _ts_param(1, CurrentUser()),
117
- _ts_metadata("design:type", Function),
118
- _ts_metadata("design:paramtypes", [
119
- Object,
120
- typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
121
- ]),
122
- _ts_metadata("design:returntype", Promise)
123
- ], EmailTemplateController.prototype, "getBySlug", null);
124
- EmailTemplateController = _ts_decorate([
125
- ApiTags('Email Template'),
126
- Controller('email/email-template'),
127
- _ts_param(0, Inject(EmailTemplateService)),
128
- _ts_metadata("design:type", Function),
129
- _ts_metadata("design:paramtypes", [
130
- typeof EmailTemplateService === "undefined" ? Object : EmailTemplateService
131
- ])
132
- ], EmailTemplateController);
@@ -1,85 +0,0 @@
1
- import { NotFoundException } from '@nestjs/common';
2
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
3
- import { EmailTemplateController } from './email-template.controller';
4
- function buildTemplate(overrides = {}) {
5
- return {
6
- id: 'template-1',
7
- slug: 'password-reset',
8
- subject: 'Reset your password',
9
- body: '<p>Hello {{name}}</p>',
10
- isActive: true,
11
- readOnly: false,
12
- createdAt: new Date(),
13
- updatedAt: new Date(),
14
- ...overrides
15
- };
16
- }
17
- describe('EmailTemplateController', ()=>{
18
- let controller;
19
- let mockEmailTemplateService;
20
- beforeEach(()=>{
21
- mockEmailTemplateService = {
22
- insert: jest.fn(),
23
- findById: jest.fn(),
24
- getAll: jest.fn(),
25
- update: jest.fn(),
26
- delete: jest.fn(),
27
- findBySlug: jest.fn()
28
- };
29
- controller = new EmailTemplateController(mockEmailTemplateService);
30
- });
31
- it('wires the injected service onto the generated controller base', ()=>{
32
- expect(controller.emailTemplateService).toBe(mockEmailTemplateService);
33
- expect(controller.service).toBe(mockEmailTemplateService);
34
- });
35
- describe('insert', ()=>{
36
- it('creates an email template and returns the mapped response', async ()=>{
37
- const user = buildMockUser();
38
- mockEmailTemplateService.insert.mockResolvedValue(buildTemplate());
39
- const result = await controller.insert({
40
- slug: 'password-reset'
41
- }, user);
42
- expect(mockEmailTemplateService.insert).toHaveBeenCalledWith({
43
- slug: 'password-reset'
44
- }, user);
45
- expect(result.success).toBe(true);
46
- expect(result.data).toEqual(expect.objectContaining({
47
- id: 'template-1'
48
- }));
49
- });
50
- });
51
- describe('getAll', ()=>{
52
- it('paginates templates and maps the response list', async ()=>{
53
- mockEmailTemplateService.getAll.mockResolvedValue({
54
- data: [
55
- buildTemplate()
56
- ],
57
- total: 1
58
- });
59
- const result = await controller.getAll({}, buildMockUser(), '');
60
- expect(mockEmailTemplateService.getAll).toHaveBeenCalledWith('', {}, buildMockUser());
61
- expect(result.data).toHaveLength(1);
62
- });
63
- });
64
- describe('getBySlug', ()=>{
65
- it('returns the template matching the given slug', async ()=>{
66
- const user = buildMockUser();
67
- mockEmailTemplateService.findBySlug.mockResolvedValue(buildTemplate());
68
- const result = await controller.getBySlug({
69
- slug: 'password-reset'
70
- }, user);
71
- expect(mockEmailTemplateService.findBySlug).toHaveBeenCalledWith('password-reset', user);
72
- expect(result.success).toBe(true);
73
- expect(result.data).toEqual(expect.objectContaining({
74
- slug: 'password-reset'
75
- }));
76
- });
77
- it('throws NotFoundException when no template matches the slug', async ()=>{
78
- const user = buildMockUser();
79
- mockEmailTemplateService.findBySlug.mockResolvedValue(null);
80
- await expect(controller.getBySlug({
81
- slug: 'missing'
82
- }, user)).rejects.toThrow(NotFoundException);
83
- });
84
- });
85
- });