@flusys/nestjs-email 5.1.1 → 5.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,7 @@ _export(exports, {
21
21
  });
22
22
  const _dtos = require("@flusys/nestjs-shared/dtos");
23
23
  const _swagger = require("@nestjs/swagger");
24
+ const _classtransformer = require("class-transformer");
24
25
  const _classvalidator = require("class-validator");
25
26
  const _enums = require("../enums");
26
27
  function _define_property(obj, key, value) {
@@ -57,6 +58,7 @@ let CreateEmailConfigDto = class CreateEmailConfigDto {
57
58
  }
58
59
  };
59
60
  _ts_decorate([
61
+ (0, _classtransformer.Expose)(),
60
62
  (0, _swagger.ApiProperty)({
61
63
  example: 'Production SMTP'
62
64
  }),
@@ -66,6 +68,7 @@ _ts_decorate([
66
68
  _ts_metadata("design:type", String)
67
69
  ], CreateEmailConfigDto.prototype, "name", void 0);
68
70
  _ts_decorate([
71
+ (0, _classtransformer.Expose)(),
69
72
  (0, _swagger.ApiProperty)({
70
73
  enum: _enums.EmailProviderTypeEnum,
71
74
  example: _enums.EmailProviderTypeEnum.SMTP
@@ -75,6 +78,7 @@ _ts_decorate([
75
78
  _ts_metadata("design:type", typeof _enums.EmailProviderTypeEnum === "undefined" ? Object : _enums.EmailProviderTypeEnum)
76
79
  ], CreateEmailConfigDto.prototype, "provider", void 0);
77
80
  _ts_decorate([
81
+ (0, _classtransformer.Expose)(),
78
82
  (0, _swagger.ApiProperty)({
79
83
  type: 'object',
80
84
  description: 'Provider-specific configuration (SMTP: host, port, secure, auth)',
@@ -85,6 +89,7 @@ _ts_decorate([
85
89
  _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
86
90
  ], CreateEmailConfigDto.prototype, "config", void 0);
87
91
  _ts_decorate([
92
+ (0, _classtransformer.Expose)(),
88
93
  (0, _swagger.ApiPropertyOptional)({
89
94
  example: 'noreply@example.com'
90
95
  }),
@@ -93,6 +98,7 @@ _ts_decorate([
93
98
  _ts_metadata("design:type", String)
94
99
  ], CreateEmailConfigDto.prototype, "fromEmail", void 0);
95
100
  _ts_decorate([
101
+ (0, _classtransformer.Expose)(),
96
102
  (0, _swagger.ApiPropertyOptional)({
97
103
  example: 'FLUSYS'
98
104
  }),
@@ -102,6 +108,7 @@ _ts_decorate([
102
108
  _ts_metadata("design:type", String)
103
109
  ], CreateEmailConfigDto.prototype, "fromName", void 0);
104
110
  _ts_decorate([
111
+ (0, _classtransformer.Expose)(),
105
112
  (0, _swagger.ApiPropertyOptional)({
106
113
  example: true
107
114
  }),
@@ -110,6 +117,7 @@ _ts_decorate([
110
117
  _ts_metadata("design:type", Boolean)
111
118
  ], CreateEmailConfigDto.prototype, "isActive", void 0);
112
119
  _ts_decorate([
120
+ (0, _classtransformer.Expose)(),
113
121
  (0, _swagger.ApiPropertyOptional)({
114
122
  example: false,
115
123
  description: 'Set as default email configuration'
@@ -124,6 +132,7 @@ let UpdateEmailConfigDto = class UpdateEmailConfigDto extends (0, _swagger.Parti
124
132
  }
125
133
  };
126
134
  _ts_decorate([
135
+ (0, _classtransformer.Expose)(),
127
136
  (0, _swagger.ApiProperty)({
128
137
  example: '123e4567-e89b-12d3-a456-426614174000'
129
138
  }),
@@ -136,3 +145,68 @@ let EmailConfigResponseDto = class EmailConfigResponseDto extends _dtos.Identity
136
145
  super(...args), _define_property(this, "name", void 0), _define_property(this, "provider", void 0), _define_property(this, "config", void 0), _define_property(this, "fromEmail", void 0), _define_property(this, "fromName", void 0), _define_property(this, "isActive", void 0), _define_property(this, "isDefault", void 0);
137
146
  }
138
147
  };
148
+ _ts_decorate([
149
+ (0, _swagger.ApiProperty)({
150
+ description: 'Human-readable name for this email configuration',
151
+ example: 'Primary Transactional Email'
152
+ }),
153
+ (0, _classtransformer.Expose)(),
154
+ _ts_metadata("design:type", String)
155
+ ], EmailConfigResponseDto.prototype, "name", void 0);
156
+ _ts_decorate([
157
+ (0, _swagger.ApiProperty)({
158
+ description: 'The email provider type used for this configuration',
159
+ enum: _enums.EmailProviderTypeEnum,
160
+ example: _enums.EmailProviderTypeEnum.SMTP
161
+ }),
162
+ (0, _classtransformer.Expose)(),
163
+ _ts_metadata("design:type", typeof _enums.EmailProviderTypeEnum === "undefined" ? Object : _enums.EmailProviderTypeEnum)
164
+ ], EmailConfigResponseDto.prototype, "provider", void 0);
165
+ _ts_decorate([
166
+ (0, _swagger.ApiProperty)({
167
+ description: 'Provider-specific configuration key-value pairs',
168
+ type: 'object',
169
+ additionalProperties: true,
170
+ example: {
171
+ host: 'smtp.example.com',
172
+ port: 587,
173
+ secure: true
174
+ }
175
+ }),
176
+ (0, _classtransformer.Expose)(),
177
+ _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
178
+ ], EmailConfigResponseDto.prototype, "config", void 0);
179
+ _ts_decorate([
180
+ (0, _swagger.ApiPropertyOptional)({
181
+ description: 'The email address used in the "From" field',
182
+ example: 'no-reply@example.com',
183
+ nullable: true
184
+ }),
185
+ (0, _classtransformer.Expose)(),
186
+ _ts_metadata("design:type", Object)
187
+ ], EmailConfigResponseDto.prototype, "fromEmail", void 0);
188
+ _ts_decorate([
189
+ (0, _swagger.ApiPropertyOptional)({
190
+ description: 'The display name used in the "From" field',
191
+ example: 'Acme Notifications',
192
+ nullable: true
193
+ }),
194
+ (0, _classtransformer.Expose)(),
195
+ _ts_metadata("design:type", Object)
196
+ ], EmailConfigResponseDto.prototype, "fromName", void 0);
197
+ _ts_decorate([
198
+ (0, _swagger.ApiProperty)({
199
+ description: 'Whether this email configuration is currently active',
200
+ example: true
201
+ }),
202
+ (0, _classtransformer.Expose)(),
203
+ _ts_metadata("design:type", Boolean)
204
+ ], EmailConfigResponseDto.prototype, "isActive", void 0);
205
+ _ts_decorate([
206
+ (0, _swagger.ApiProperty)({
207
+ description: 'Whether this is the default email configuration',
208
+ example: false
209
+ }),
210
+ (0, _classtransformer.Expose)(),
211
+ _ts_metadata("design:type", Boolean)
212
+ ], EmailConfigResponseDto.prototype, "isDefault", void 0);
@@ -21,6 +21,7 @@ _export(exports, {
21
21
  });
22
22
  const _dtos = require("@flusys/nestjs-shared/dtos");
23
23
  const _swagger = require("@nestjs/swagger");
24
+ const _classtransformer = require("class-transformer");
24
25
  const _classvalidator = require("class-validator");
25
26
  function _define_property(obj, key, value) {
26
27
  if (key in obj) {
@@ -157,45 +158,95 @@ let EmailTemplateResponseDto = class EmailTemplateResponseDto extends _dtos.Iden
157
158
  }
158
159
  };
159
160
  _ts_decorate([
160
- (0, _swagger.ApiProperty)(),
161
+ (0, _swagger.ApiProperty)({
162
+ description: 'Human-readable name of the email template',
163
+ example: 'Welcome Email'
164
+ }),
165
+ (0, _classtransformer.Expose)(),
161
166
  _ts_metadata("design:type", String)
162
167
  ], EmailTemplateResponseDto.prototype, "name", void 0);
163
168
  _ts_decorate([
164
- (0, _swagger.ApiProperty)(),
169
+ (0, _swagger.ApiProperty)({
170
+ description: 'URL-friendly unique identifier for the template',
171
+ example: 'welcome-email'
172
+ }),
173
+ (0, _classtransformer.Expose)(),
165
174
  _ts_metadata("design:type", String)
166
175
  ], EmailTemplateResponseDto.prototype, "slug", void 0);
167
176
  _ts_decorate([
168
- (0, _swagger.ApiPropertyOptional)(),
177
+ (0, _swagger.ApiPropertyOptional)({
178
+ description: 'Optional description of the template purpose',
179
+ example: 'Sent to new users upon successful registration',
180
+ nullable: true
181
+ }),
182
+ (0, _classtransformer.Expose)(),
169
183
  _ts_metadata("design:type", Object)
170
184
  ], EmailTemplateResponseDto.prototype, "description", void 0);
171
185
  _ts_decorate([
172
- (0, _swagger.ApiProperty)(),
186
+ (0, _swagger.ApiProperty)({
187
+ description: 'Email subject line, supports template variables',
188
+ example: 'Welcome to Acme, {{firstName}}!'
189
+ }),
190
+ (0, _classtransformer.Expose)(),
173
191
  _ts_metadata("design:type", String)
174
192
  ], EmailTemplateResponseDto.prototype, "subject", void 0);
175
193
  _ts_decorate([
176
194
  (0, _swagger.ApiProperty)({
195
+ description: 'JSON schema defining the variables accepted by this template',
177
196
  type: 'object',
178
- additionalProperties: true
197
+ additionalProperties: true,
198
+ example: {
199
+ firstName: {
200
+ type: 'string'
201
+ },
202
+ activationUrl: {
203
+ type: 'string',
204
+ format: 'uri'
205
+ }
206
+ }
179
207
  }),
208
+ (0, _classtransformer.Expose)(),
180
209
  _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
181
210
  ], EmailTemplateResponseDto.prototype, "schema", void 0);
182
211
  _ts_decorate([
183
- (0, _swagger.ApiProperty)(),
212
+ (0, _swagger.ApiProperty)({
213
+ description: 'HTML body of the email template',
214
+ example: '<h1>Welcome, {{firstName}}!</h1><p>Click <a href="{{activationUrl}}">here</a> to activate.</p>'
215
+ }),
216
+ (0, _classtransformer.Expose)(),
184
217
  _ts_metadata("design:type", String)
185
218
  ], EmailTemplateResponseDto.prototype, "htmlContent", void 0);
186
219
  _ts_decorate([
187
- (0, _swagger.ApiPropertyOptional)(),
220
+ (0, _swagger.ApiPropertyOptional)({
221
+ description: 'Plain-text fallback body for email clients that do not render HTML',
222
+ example: 'Welcome, {{firstName}}! Activate your account at {{activationUrl}}',
223
+ nullable: true
224
+ }),
225
+ (0, _classtransformer.Expose)(),
188
226
  _ts_metadata("design:type", Object)
189
227
  ], EmailTemplateResponseDto.prototype, "textContent", void 0);
190
228
  _ts_decorate([
191
- (0, _swagger.ApiProperty)(),
229
+ (0, _swagger.ApiProperty)({
230
+ description: 'Version number of the schema definition for this template',
231
+ example: 1,
232
+ minimum: 1
233
+ }),
234
+ (0, _classtransformer.Expose)(),
192
235
  _ts_metadata("design:type", Number)
193
236
  ], EmailTemplateResponseDto.prototype, "schemaVersion", void 0);
194
237
  _ts_decorate([
195
- (0, _swagger.ApiProperty)(),
238
+ (0, _swagger.ApiProperty)({
239
+ description: 'Whether this template is currently active and usable',
240
+ example: true
241
+ }),
242
+ (0, _classtransformer.Expose)(),
196
243
  _ts_metadata("design:type", Boolean)
197
244
  ], EmailTemplateResponseDto.prototype, "isActive", void 0);
198
245
  _ts_decorate([
199
- (0, _swagger.ApiProperty)(),
246
+ (0, _swagger.ApiProperty)({
247
+ description: 'Whether this template renders as HTML; false means plain-text only',
248
+ example: true
249
+ }),
250
+ (0, _classtransformer.Expose)(),
200
251
  _ts_metadata("design:type", Boolean)
201
252
  ], EmailTemplateResponseDto.prototype, "isHtml", void 0);
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "EmailDataSourceProvider", {
9
9
  }
10
10
  });
11
11
  const _modules = require("@flusys/nestjs-shared/modules");
12
- const _constants = require("@flusys/nestjs-shared/constants");
13
12
  const _common = require("@nestjs/common");
14
13
  const _core = require("@nestjs/core");
15
14
  const _express = require("express");
@@ -43,7 +42,6 @@ function _ts_param(paramIndex, decorator) {
43
42
  };
44
43
  }
45
44
  let EmailDataSourceProvider = class EmailDataSourceProvider extends _modules.MultiTenantDataSourceService {
46
- // ─── Factory Methods ────────────────────────────────────────────────────────
47
45
  static buildParentOptions(options) {
48
46
  return {
49
47
  bootstrapAppConfig: options.bootstrapAppConfig,
@@ -52,61 +50,15 @@ let EmailDataSourceProvider = class EmailDataSourceProvider extends _modules.Mul
52
50
  tenants: options.config?.tenants
53
51
  };
54
52
  }
55
- // ─── Feature Flags ──────────────────────────────────────────────────────────
56
53
  getEnableCompanyFeatureForTenant(tenant) {
57
54
  return tenant?.enableCompanyFeature ?? this.configService.isCompanyFeatureEnabled();
58
55
  }
59
- // ─── Overrides ──────────────────────────────────────────────────────────────
60
56
  async createDataSourceFromConfig(config) {
61
57
  const currentTenant = this.getCurrentTenant();
62
58
  const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
63
59
  const entities = (0, _entities.getEmailEntitiesByConfig)(enableCompanyFeature);
64
60
  return super.createDataSourceFromConfig(config, entities);
65
61
  }
66
- async getSingleDataSource() {
67
- if (EmailDataSourceProvider.singleDataSource?.isInitialized) {
68
- return EmailDataSourceProvider.singleDataSource;
69
- }
70
- if (EmailDataSourceProvider.singleConnectionLock) {
71
- return EmailDataSourceProvider.singleConnectionLock;
72
- }
73
- const config = this.getDefaultDatabaseConfig();
74
- if (!config) {
75
- throw new _common.InternalServerErrorException({
76
- message: 'No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.',
77
- messageKey: _constants.SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
78
- });
79
- }
80
- const connectionPromise = this.createDataSourceFromConfig(config);
81
- EmailDataSourceProvider.singleConnectionLock = connectionPromise;
82
- try {
83
- const dataSource = await connectionPromise;
84
- EmailDataSourceProvider.singleDataSource = dataSource;
85
- return dataSource;
86
- } finally{
87
- EmailDataSourceProvider.singleConnectionLock = null;
88
- }
89
- }
90
- async getOrCreateTenantConnection(tenant) {
91
- const existing = EmailDataSourceProvider.tenantConnections.get(tenant.id);
92
- if (existing?.isInitialized) {
93
- return existing;
94
- }
95
- const pendingConnection = EmailDataSourceProvider.connectionLocks.get(tenant.id);
96
- if (pendingConnection) {
97
- return pendingConnection;
98
- }
99
- const config = this.buildTenantDatabaseConfig(tenant);
100
- const connectionPromise = this.createDataSourceFromConfig(config);
101
- EmailDataSourceProvider.connectionLocks.set(tenant.id, connectionPromise);
102
- try {
103
- const dataSource = await connectionPromise;
104
- EmailDataSourceProvider.tenantConnections.set(tenant.id, dataSource);
105
- return dataSource;
106
- } finally{
107
- EmailDataSourceProvider.connectionLocks.delete(tenant.id);
108
- }
109
- }
110
62
  constructor(configService, request){
111
63
  super(EmailDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
112
64
  }
@@ -42,13 +42,10 @@ function _ts_param(paramIndex, decorator) {
42
42
  decorator(target, key, paramIndex);
43
43
  };
44
44
  }
45
- let EmailProviderConfigService = class EmailProviderConfigService extends _classes.RequestScopedApiService {
45
+ let EmailProviderConfigService = class EmailProviderConfigService extends _classes.ApiService {
46
46
  resolveEntity() {
47
47
  return this.emailConfig.isCompanyFeatureEnabled() ? _entities.EmailConfigWithCompany : _entities.EmailConfig;
48
48
  }
49
- getDataSourceProvider() {
50
- return this.dataSourceProvider;
51
- }
52
49
  async convertSingleDtoToEntity(dto, user) {
53
50
  const entity = {
54
51
  ...dto
@@ -90,7 +87,7 @@ let EmailProviderConfigService = class EmailProviderConfigService extends _class
90
87
  return result;
91
88
  }
92
89
  async findByIdDirect(id) {
93
- await this.ensureRepositoryInitialized();
90
+ await this.ensureDataSourceRepository();
94
91
  return this.repository.findOne({
95
92
  where: {
96
93
  id
@@ -98,7 +95,7 @@ let EmailProviderConfigService = class EmailProviderConfigService extends _class
98
95
  });
99
96
  }
100
97
  async getDefaultConfig(user) {
101
- await this.ensureRepositoryInitialized();
98
+ await this.ensureDataSourceRepository();
102
99
  const baseWhere = (0, _utils.buildCompanyWhereCondition)({
103
100
  isActive: true
104
101
  }, this.emailConfig.isCompanyFeatureEnabled(), user);
@@ -119,7 +116,7 @@ let EmailProviderConfigService = class EmailProviderConfigService extends _class
119
116
  });
120
117
  }
121
118
  constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
122
- super('emailConfig', null, cacheManager, utilsService, EmailProviderConfigService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
119
+ super('emailConfig', cacheManager, utilsService, EmailProviderConfigService.name, true, 'email', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig;
123
120
  }
124
121
  };
125
122
  EmailProviderConfigService = _ts_decorate([
@@ -57,13 +57,10 @@ const DEFAULT_SELECT_FIELDS = [
57
57
  'createdAt',
58
58
  'updatedAt'
59
59
  ];
60
- let EmailTemplateService = class EmailTemplateService extends _classes.RequestScopedApiService {
60
+ let EmailTemplateService = class EmailTemplateService extends _classes.ApiService {
61
61
  resolveEntity() {
62
62
  return this.emailConfig.isCompanyFeatureEnabled() ? _entities.EmailTemplateWithCompany : _entities.EmailTemplate;
63
63
  }
64
- getDataSourceProvider() {
65
- return this.dataSourceProvider;
66
- }
67
64
  async convertSingleDtoToEntity(dto, user) {
68
65
  const entity = await super.convertSingleDtoToEntity(dto, user);
69
66
  await this.incrementSchemaVersionIfChanged(dto, entity);
@@ -96,7 +93,7 @@ let EmailTemplateService = class EmailTemplateService extends _classes.RequestSc
96
93
  }
97
94
  // ─── Public Query Methods ───────────────────────────────────────────────────
98
95
  async findByIdDirect(id) {
99
- await this.ensureRepositoryInitialized();
96
+ await this.ensureDataSourceRepository();
100
97
  return this.repository.findOne({
101
98
  where: {
102
99
  id
@@ -104,7 +101,7 @@ let EmailTemplateService = class EmailTemplateService extends _classes.RequestSc
104
101
  });
105
102
  }
106
103
  async findBySlug(slug, user) {
107
- await this.ensureRepositoryInitialized();
104
+ await this.ensureDataSourceRepository();
108
105
  const where = (0, _utils.buildCompanyWhereCondition)({
109
106
  slug,
110
107
  isActive: true
@@ -117,7 +114,7 @@ let EmailTemplateService = class EmailTemplateService extends _classes.RequestSc
117
114
  async incrementSchemaVersionIfChanged(dto, entity) {
118
115
  const updateDto = dto;
119
116
  if (!updateDto.id || !dto.schema) return;
120
- await this.ensureRepositoryInitialized();
117
+ await this.ensureDataSourceRepository();
121
118
  const existing = await this.repository.findOne({
122
119
  where: {
123
120
  id: updateDto.id
@@ -128,7 +125,7 @@ let EmailTemplateService = class EmailTemplateService extends _classes.RequestSc
128
125
  }
129
126
  }
130
127
  constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
131
- super('emailTemplate', null, cacheManager, utilsService, EmailTemplateService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
128
+ super('emailTemplate', cacheManager, utilsService, EmailTemplateService.name, true, 'email', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig;
132
129
  }
133
130
  };
134
131
  EmailTemplateService = _ts_decorate([
@@ -1,9 +1,9 @@
1
1
  import { CreateEmailConfigDto, EmailConfigResponseDto, UpdateEmailConfigDto } from '../dtos';
2
2
  import { EmailProviderConfigService } from '../services';
3
3
  declare const EmailConfigController_base: abstract new (service: EmailProviderConfigService) => {
4
- readonly enabledEndpoints: import("@flusys/nestjs-shared/classes").ApiEndpoint[] | "all";
4
+ readonly enabledEndpoints: import("@flusys/nestjs-shared").ApiEndpoint[] | "all";
5
5
  service: EmailProviderConfigService;
6
- isEnabled(endpoint: import("@flusys/nestjs-shared/classes").ApiEndpoint): boolean;
6
+ isEnabled(endpoint: import("@flusys/nestjs-shared").ApiEndpoint): boolean;
7
7
  insert(addDto: CreateEmailConfigDto, user: import("@flusys/nestjs-shared").ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<EmailConfigResponseDto>>;
8
8
  insertMany(addDto: CreateEmailConfigDto[], user: import("@flusys/nestjs-shared").ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<EmailConfigResponseDto>>;
9
9
  getById(id: string, body: import("@flusys/nestjs-shared").GetByIdBodyDto, user: import("@flusys/nestjs-shared").ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").SingleResponseDto<EmailConfigResponseDto>>;
@@ -4,19 +4,19 @@ import { CreateEmailTemplateDto, EmailTemplateResponseDto, UpdateEmailTemplateDt
4
4
  import { IEmailTemplate } from '../interfaces';
5
5
  import { EmailTemplateService } from '../services';
6
6
  declare const EmailTemplateController_base: abstract new (service: EmailTemplateService) => {
7
- readonly enabledEndpoints: import("@flusys/nestjs-shared/classes").ApiEndpoint[] | "all";
7
+ readonly enabledEndpoints: import("@flusys/nestjs-shared").ApiEndpoint[] | "all";
8
8
  service: EmailTemplateService;
9
- isEnabled(endpoint: import("@flusys/nestjs-shared/classes").ApiEndpoint): boolean;
9
+ isEnabled(endpoint: import("@flusys/nestjs-shared").ApiEndpoint): boolean;
10
10
  insert(addDto: CreateEmailTemplateDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<EmailTemplateResponseDto>>;
11
- insertMany(addDto: CreateEmailTemplateDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").BulkResponseDto<EmailTemplateResponseDto>>;
12
- getById(id: string, body: import("@flusys/nestjs-shared/dtos").GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<EmailTemplateResponseDto>>;
13
- getByIds(body: import("@flusys/nestjs-shared/dtos").GetByIdsDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").ListResponseDto<EmailTemplateResponseDto>>;
11
+ insertMany(addDto: CreateEmailTemplateDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<EmailTemplateResponseDto>>;
12
+ getById(id: string, body: import("@flusys/nestjs-shared").GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<EmailTemplateResponseDto>>;
13
+ getByIds(body: import("@flusys/nestjs-shared").GetByIdsDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").ListResponseDto<EmailTemplateResponseDto>>;
14
14
  update(updateDto: UpdateEmailTemplateDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<EmailTemplateResponseDto>>;
15
- updateMany(updateDtos: UpdateEmailTemplateDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").BulkResponseDto<EmailTemplateResponseDto>>;
16
- bulkUpsert(dtos: (CreateEmailTemplateDto | UpdateEmailTemplateDto)[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").BulkResponseDto<EmailTemplateResponseDto>>;
15
+ updateMany(updateDtos: UpdateEmailTemplateDto[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<EmailTemplateResponseDto>>;
16
+ bulkUpsert(dtos: (CreateEmailTemplateDto | UpdateEmailTemplateDto)[], user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").BulkResponseDto<EmailTemplateResponseDto>>;
17
17
  getByFilter(filter: Record<string, any>, user: ILoggedUserInfo | null): Promise<SingleResponseDto<EmailTemplateResponseDto>>;
18
- getAll(filterAndPaginationDto: import("@flusys/nestjs-shared/dtos").FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<import("@flusys/nestjs-shared/dtos").ListResponseDto<EmailTemplateResponseDto>>;
19
- delete(deleteDto: import("@flusys/nestjs-shared/dtos").DeleteDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared/dtos").MessageResponseDto>;
18
+ getAll(filterAndPaginationDto: import("@flusys/nestjs-shared").FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<import("@flusys/nestjs-shared").ListResponseDto<EmailTemplateResponseDto>>;
19
+ delete(deleteDto: import("@flusys/nestjs-shared").DeleteDto, user: ILoggedUserInfo | null): Promise<import("@flusys/nestjs-shared").MessageResponseDto>;
20
20
  };
21
21
  export declare class EmailTemplateController extends EmailTemplateController_base {
22
22
  emailTemplateService: EmailTemplateService;
@@ -22,6 +22,7 @@ function _ts_metadata(k, v) {
22
22
  }
23
23
  import { IdentityResponseDto } from '@flusys/nestjs-shared/dtos';
24
24
  import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
25
+ import { Expose } from 'class-transformer';
25
26
  import { IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';
26
27
  import { EmailProviderTypeEnum } from '../enums';
27
28
  export class CreateEmailConfigDto {
@@ -36,6 +37,7 @@ export class CreateEmailConfigDto {
36
37
  }
37
38
  }
38
39
  _ts_decorate([
40
+ Expose(),
39
41
  ApiProperty({
40
42
  example: 'Production SMTP'
41
43
  }),
@@ -45,6 +47,7 @@ _ts_decorate([
45
47
  _ts_metadata("design:type", String)
46
48
  ], CreateEmailConfigDto.prototype, "name", void 0);
47
49
  _ts_decorate([
50
+ Expose(),
48
51
  ApiProperty({
49
52
  enum: EmailProviderTypeEnum,
50
53
  example: EmailProviderTypeEnum.SMTP
@@ -54,6 +57,7 @@ _ts_decorate([
54
57
  _ts_metadata("design:type", typeof EmailProviderTypeEnum === "undefined" ? Object : EmailProviderTypeEnum)
55
58
  ], CreateEmailConfigDto.prototype, "provider", void 0);
56
59
  _ts_decorate([
60
+ Expose(),
57
61
  ApiProperty({
58
62
  type: 'object',
59
63
  description: 'Provider-specific configuration (SMTP: host, port, secure, auth)',
@@ -64,6 +68,7 @@ _ts_decorate([
64
68
  _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
65
69
  ], CreateEmailConfigDto.prototype, "config", void 0);
66
70
  _ts_decorate([
71
+ Expose(),
67
72
  ApiPropertyOptional({
68
73
  example: 'noreply@example.com'
69
74
  }),
@@ -72,6 +77,7 @@ _ts_decorate([
72
77
  _ts_metadata("design:type", String)
73
78
  ], CreateEmailConfigDto.prototype, "fromEmail", void 0);
74
79
  _ts_decorate([
80
+ Expose(),
75
81
  ApiPropertyOptional({
76
82
  example: 'FLUSYS'
77
83
  }),
@@ -81,6 +87,7 @@ _ts_decorate([
81
87
  _ts_metadata("design:type", String)
82
88
  ], CreateEmailConfigDto.prototype, "fromName", void 0);
83
89
  _ts_decorate([
90
+ Expose(),
84
91
  ApiPropertyOptional({
85
92
  example: true
86
93
  }),
@@ -89,6 +96,7 @@ _ts_decorate([
89
96
  _ts_metadata("design:type", Boolean)
90
97
  ], CreateEmailConfigDto.prototype, "isActive", void 0);
91
98
  _ts_decorate([
99
+ Expose(),
92
100
  ApiPropertyOptional({
93
101
  example: false,
94
102
  description: 'Set as default email configuration'
@@ -103,6 +111,7 @@ export class UpdateEmailConfigDto extends PartialType(CreateEmailConfigDto) {
103
111
  }
104
112
  }
105
113
  _ts_decorate([
114
+ Expose(),
106
115
  ApiProperty({
107
116
  example: '123e4567-e89b-12d3-a456-426614174000'
108
117
  }),
@@ -115,3 +124,68 @@ export class EmailConfigResponseDto extends IdentityResponseDto {
115
124
  super(...args), _define_property(this, "name", void 0), _define_property(this, "provider", void 0), _define_property(this, "config", void 0), _define_property(this, "fromEmail", void 0), _define_property(this, "fromName", void 0), _define_property(this, "isActive", void 0), _define_property(this, "isDefault", void 0);
116
125
  }
117
126
  }
127
+ _ts_decorate([
128
+ ApiProperty({
129
+ description: 'Human-readable name for this email configuration',
130
+ example: 'Primary Transactional Email'
131
+ }),
132
+ Expose(),
133
+ _ts_metadata("design:type", String)
134
+ ], EmailConfigResponseDto.prototype, "name", void 0);
135
+ _ts_decorate([
136
+ ApiProperty({
137
+ description: 'The email provider type used for this configuration',
138
+ enum: EmailProviderTypeEnum,
139
+ example: EmailProviderTypeEnum.SMTP
140
+ }),
141
+ Expose(),
142
+ _ts_metadata("design:type", typeof EmailProviderTypeEnum === "undefined" ? Object : EmailProviderTypeEnum)
143
+ ], EmailConfigResponseDto.prototype, "provider", void 0);
144
+ _ts_decorate([
145
+ ApiProperty({
146
+ description: 'Provider-specific configuration key-value pairs',
147
+ type: 'object',
148
+ additionalProperties: true,
149
+ example: {
150
+ host: 'smtp.example.com',
151
+ port: 587,
152
+ secure: true
153
+ }
154
+ }),
155
+ Expose(),
156
+ _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
157
+ ], EmailConfigResponseDto.prototype, "config", void 0);
158
+ _ts_decorate([
159
+ ApiPropertyOptional({
160
+ description: 'The email address used in the "From" field',
161
+ example: 'no-reply@example.com',
162
+ nullable: true
163
+ }),
164
+ Expose(),
165
+ _ts_metadata("design:type", Object)
166
+ ], EmailConfigResponseDto.prototype, "fromEmail", void 0);
167
+ _ts_decorate([
168
+ ApiPropertyOptional({
169
+ description: 'The display name used in the "From" field',
170
+ example: 'Acme Notifications',
171
+ nullable: true
172
+ }),
173
+ Expose(),
174
+ _ts_metadata("design:type", Object)
175
+ ], EmailConfigResponseDto.prototype, "fromName", void 0);
176
+ _ts_decorate([
177
+ ApiProperty({
178
+ description: 'Whether this email configuration is currently active',
179
+ example: true
180
+ }),
181
+ Expose(),
182
+ _ts_metadata("design:type", Boolean)
183
+ ], EmailConfigResponseDto.prototype, "isActive", void 0);
184
+ _ts_decorate([
185
+ ApiProperty({
186
+ description: 'Whether this is the default email configuration',
187
+ example: false
188
+ }),
189
+ Expose(),
190
+ _ts_metadata("design:type", Boolean)
191
+ ], EmailConfigResponseDto.prototype, "isDefault", void 0);
@@ -22,6 +22,7 @@ function _ts_metadata(k, v) {
22
22
  }
23
23
  import { IdentityResponseDto } from '@flusys/nestjs-shared/dtos';
24
24
  import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
25
+ import { Expose } from 'class-transformer';
25
26
  import { IsBoolean, IsNotEmpty, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';
26
27
  export class CreateEmailTemplateDto {
27
28
  constructor(){
@@ -136,45 +137,95 @@ export class EmailTemplateResponseDto extends IdentityResponseDto {
136
137
  }
137
138
  }
138
139
  _ts_decorate([
139
- ApiProperty(),
140
+ ApiProperty({
141
+ description: 'Human-readable name of the email template',
142
+ example: 'Welcome Email'
143
+ }),
144
+ Expose(),
140
145
  _ts_metadata("design:type", String)
141
146
  ], EmailTemplateResponseDto.prototype, "name", void 0);
142
147
  _ts_decorate([
143
- ApiProperty(),
148
+ ApiProperty({
149
+ description: 'URL-friendly unique identifier for the template',
150
+ example: 'welcome-email'
151
+ }),
152
+ Expose(),
144
153
  _ts_metadata("design:type", String)
145
154
  ], EmailTemplateResponseDto.prototype, "slug", void 0);
146
155
  _ts_decorate([
147
- ApiPropertyOptional(),
156
+ ApiPropertyOptional({
157
+ description: 'Optional description of the template purpose',
158
+ example: 'Sent to new users upon successful registration',
159
+ nullable: true
160
+ }),
161
+ Expose(),
148
162
  _ts_metadata("design:type", Object)
149
163
  ], EmailTemplateResponseDto.prototype, "description", void 0);
150
164
  _ts_decorate([
151
- ApiProperty(),
165
+ ApiProperty({
166
+ description: 'Email subject line, supports template variables',
167
+ example: 'Welcome to Acme, {{firstName}}!'
168
+ }),
169
+ Expose(),
152
170
  _ts_metadata("design:type", String)
153
171
  ], EmailTemplateResponseDto.prototype, "subject", void 0);
154
172
  _ts_decorate([
155
173
  ApiProperty({
174
+ description: 'JSON schema defining the variables accepted by this template',
156
175
  type: 'object',
157
- additionalProperties: true
176
+ additionalProperties: true,
177
+ example: {
178
+ firstName: {
179
+ type: 'string'
180
+ },
181
+ activationUrl: {
182
+ type: 'string',
183
+ format: 'uri'
184
+ }
185
+ }
158
186
  }),
187
+ Expose(),
159
188
  _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
160
189
  ], EmailTemplateResponseDto.prototype, "schema", void 0);
161
190
  _ts_decorate([
162
- ApiProperty(),
191
+ ApiProperty({
192
+ description: 'HTML body of the email template',
193
+ example: '<h1>Welcome, {{firstName}}!</h1><p>Click <a href="{{activationUrl}}">here</a> to activate.</p>'
194
+ }),
195
+ Expose(),
163
196
  _ts_metadata("design:type", String)
164
197
  ], EmailTemplateResponseDto.prototype, "htmlContent", void 0);
165
198
  _ts_decorate([
166
- ApiPropertyOptional(),
199
+ ApiPropertyOptional({
200
+ description: 'Plain-text fallback body for email clients that do not render HTML',
201
+ example: 'Welcome, {{firstName}}! Activate your account at {{activationUrl}}',
202
+ nullable: true
203
+ }),
204
+ Expose(),
167
205
  _ts_metadata("design:type", Object)
168
206
  ], EmailTemplateResponseDto.prototype, "textContent", void 0);
169
207
  _ts_decorate([
170
- ApiProperty(),
208
+ ApiProperty({
209
+ description: 'Version number of the schema definition for this template',
210
+ example: 1,
211
+ minimum: 1
212
+ }),
213
+ Expose(),
171
214
  _ts_metadata("design:type", Number)
172
215
  ], EmailTemplateResponseDto.prototype, "schemaVersion", void 0);
173
216
  _ts_decorate([
174
- ApiProperty(),
217
+ ApiProperty({
218
+ description: 'Whether this template is currently active and usable',
219
+ example: true
220
+ }),
221
+ Expose(),
175
222
  _ts_metadata("design:type", Boolean)
176
223
  ], EmailTemplateResponseDto.prototype, "isActive", void 0);
177
224
  _ts_decorate([
178
- ApiProperty(),
225
+ ApiProperty({
226
+ description: 'Whether this template renders as HTML; false means plain-text only',
227
+ example: true
228
+ }),
229
+ Expose(),
179
230
  _ts_metadata("design:type", Boolean)
180
231
  ], EmailTemplateResponseDto.prototype, "isHtml", void 0);
@@ -26,14 +26,12 @@ function _ts_param(paramIndex, decorator) {
26
26
  };
27
27
  }
28
28
  import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
29
- import { SYSTEM_MESSAGES } from '@flusys/nestjs-shared/constants';
30
- import { Inject, Injectable, InternalServerErrorException, Optional, Scope } from '@nestjs/common';
29
+ import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
31
30
  import { REQUEST } from '@nestjs/core';
32
31
  import { Request } from 'express';
33
32
  import { getEmailEntitiesByConfig } from '../entities';
34
33
  import { EmailConfigService } from './email-config.service';
35
34
  export class EmailDataSourceProvider extends MultiTenantDataSourceService {
36
- // ─── Factory Methods ────────────────────────────────────────────────────────
37
35
  static buildParentOptions(options) {
38
36
  return {
39
37
  bootstrapAppConfig: options.bootstrapAppConfig,
@@ -42,61 +40,15 @@ export class EmailDataSourceProvider extends MultiTenantDataSourceService {
42
40
  tenants: options.config?.tenants
43
41
  };
44
42
  }
45
- // ─── Feature Flags ──────────────────────────────────────────────────────────
46
43
  getEnableCompanyFeatureForTenant(tenant) {
47
44
  return tenant?.enableCompanyFeature ?? this.configService.isCompanyFeatureEnabled();
48
45
  }
49
- // ─── Overrides ──────────────────────────────────────────────────────────────
50
46
  async createDataSourceFromConfig(config) {
51
47
  const currentTenant = this.getCurrentTenant();
52
48
  const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
53
49
  const entities = getEmailEntitiesByConfig(enableCompanyFeature);
54
50
  return super.createDataSourceFromConfig(config, entities);
55
51
  }
56
- async getSingleDataSource() {
57
- if (EmailDataSourceProvider.singleDataSource?.isInitialized) {
58
- return EmailDataSourceProvider.singleDataSource;
59
- }
60
- if (EmailDataSourceProvider.singleConnectionLock) {
61
- return EmailDataSourceProvider.singleConnectionLock;
62
- }
63
- const config = this.getDefaultDatabaseConfig();
64
- if (!config) {
65
- throw new InternalServerErrorException({
66
- message: 'No database config available. Provide defaultDatabaseConfig or tenantDefaultDatabaseConfig.',
67
- messageKey: SYSTEM_MESSAGES.DATABASE_CONFIG_NOT_AVAILABLE
68
- });
69
- }
70
- const connectionPromise = this.createDataSourceFromConfig(config);
71
- EmailDataSourceProvider.singleConnectionLock = connectionPromise;
72
- try {
73
- const dataSource = await connectionPromise;
74
- EmailDataSourceProvider.singleDataSource = dataSource;
75
- return dataSource;
76
- } finally{
77
- EmailDataSourceProvider.singleConnectionLock = null;
78
- }
79
- }
80
- async getOrCreateTenantConnection(tenant) {
81
- const existing = EmailDataSourceProvider.tenantConnections.get(tenant.id);
82
- if (existing?.isInitialized) {
83
- return existing;
84
- }
85
- const pendingConnection = EmailDataSourceProvider.connectionLocks.get(tenant.id);
86
- if (pendingConnection) {
87
- return pendingConnection;
88
- }
89
- const config = this.buildTenantDatabaseConfig(tenant);
90
- const connectionPromise = this.createDataSourceFromConfig(config);
91
- EmailDataSourceProvider.connectionLocks.set(tenant.id, connectionPromise);
92
- try {
93
- const dataSource = await connectionPromise;
94
- EmailDataSourceProvider.tenantConnections.set(tenant.id, dataSource);
95
- return dataSource;
96
- } finally{
97
- EmailDataSourceProvider.connectionLocks.delete(tenant.id);
98
- }
99
- }
100
52
  constructor(configService, request){
101
53
  super(EmailDataSourceProvider.buildParentOptions(configService.getOptions()), request), _define_property(this, "configService", void 0), this.configService = configService;
102
54
  }
@@ -25,20 +25,17 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
28
+ import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
29
29
  import { UtilsService } from '@flusys/nestjs-shared/modules';
30
30
  import { applyCompanyFilter, buildCompanyWhereCondition } from '@flusys/nestjs-shared/utils';
31
31
  import { Inject, Injectable, Scope } from '@nestjs/common';
32
32
  import { EmailConfig, EmailConfigWithCompany } from '../entities';
33
33
  import { EmailConfigService } from './email-config.service';
34
34
  import { EmailDataSourceProvider } from './email-datasource.provider';
35
- export class EmailProviderConfigService extends RequestScopedApiService {
35
+ export class EmailProviderConfigService extends ApiService {
36
36
  resolveEntity() {
37
37
  return this.emailConfig.isCompanyFeatureEnabled() ? EmailConfigWithCompany : EmailConfig;
38
38
  }
39
- getDataSourceProvider() {
40
- return this.dataSourceProvider;
41
- }
42
39
  async convertSingleDtoToEntity(dto, user) {
43
40
  const entity = {
44
41
  ...dto
@@ -80,7 +77,7 @@ export class EmailProviderConfigService extends RequestScopedApiService {
80
77
  return result;
81
78
  }
82
79
  async findByIdDirect(id) {
83
- await this.ensureRepositoryInitialized();
80
+ await this.ensureDataSourceRepository();
84
81
  return this.repository.findOne({
85
82
  where: {
86
83
  id
@@ -88,7 +85,7 @@ export class EmailProviderConfigService extends RequestScopedApiService {
88
85
  });
89
86
  }
90
87
  async getDefaultConfig(user) {
91
- await this.ensureRepositoryInitialized();
88
+ await this.ensureDataSourceRepository();
92
89
  const baseWhere = buildCompanyWhereCondition({
93
90
  isActive: true
94
91
  }, this.emailConfig.isCompanyFeatureEnabled(), user);
@@ -109,7 +106,7 @@ export class EmailProviderConfigService extends RequestScopedApiService {
109
106
  });
110
107
  }
111
108
  constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
112
- super('emailConfig', null, cacheManager, utilsService, EmailProviderConfigService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
109
+ super('emailConfig', cacheManager, utilsService, EmailProviderConfigService.name, true, 'email', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig;
113
110
  }
114
111
  }
115
112
  EmailProviderConfigService = _ts_decorate([
@@ -25,7 +25,7 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
28
+ import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
29
29
  import { UtilsService } from '@flusys/nestjs-shared/modules';
30
30
  import { applyCompanyFilter, buildCompanyWhereCondition } from '@flusys/nestjs-shared/utils';
31
31
  import { Inject, Injectable, Scope } from '@nestjs/common';
@@ -47,13 +47,10 @@ const DEFAULT_SELECT_FIELDS = [
47
47
  'createdAt',
48
48
  'updatedAt'
49
49
  ];
50
- export class EmailTemplateService extends RequestScopedApiService {
50
+ export class EmailTemplateService extends ApiService {
51
51
  resolveEntity() {
52
52
  return this.emailConfig.isCompanyFeatureEnabled() ? EmailTemplateWithCompany : EmailTemplate;
53
53
  }
54
- getDataSourceProvider() {
55
- return this.dataSourceProvider;
56
- }
57
54
  async convertSingleDtoToEntity(dto, user) {
58
55
  const entity = await super.convertSingleDtoToEntity(dto, user);
59
56
  await this.incrementSchemaVersionIfChanged(dto, entity);
@@ -86,7 +83,7 @@ export class EmailTemplateService extends RequestScopedApiService {
86
83
  }
87
84
  // ─── Public Query Methods ───────────────────────────────────────────────────
88
85
  async findByIdDirect(id) {
89
- await this.ensureRepositoryInitialized();
86
+ await this.ensureDataSourceRepository();
90
87
  return this.repository.findOne({
91
88
  where: {
92
89
  id
@@ -94,7 +91,7 @@ export class EmailTemplateService extends RequestScopedApiService {
94
91
  });
95
92
  }
96
93
  async findBySlug(slug, user) {
97
- await this.ensureRepositoryInitialized();
94
+ await this.ensureDataSourceRepository();
98
95
  const where = buildCompanyWhereCondition({
99
96
  slug,
100
97
  isActive: true
@@ -107,7 +104,7 @@ export class EmailTemplateService extends RequestScopedApiService {
107
104
  async incrementSchemaVersionIfChanged(dto, entity) {
108
105
  const updateDto = dto;
109
106
  if (!updateDto.id || !dto.schema) return;
110
- await this.ensureRepositoryInitialized();
107
+ await this.ensureDataSourceRepository();
111
108
  const existing = await this.repository.findOne({
112
109
  where: {
113
110
  id: updateDto.id
@@ -118,7 +115,7 @@ export class EmailTemplateService extends RequestScopedApiService {
118
115
  }
119
116
  }
120
117
  constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
121
- super('emailTemplate', null, cacheManager, utilsService, EmailTemplateService.name, true, 'email'), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig, this.dataSourceProvider = dataSourceProvider;
118
+ super('emailTemplate', cacheManager, utilsService, EmailTemplateService.name, true, 'email', undefined, dataSourceProvider), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig;
122
119
  }
123
120
  }
124
121
  EmailTemplateService = _ts_decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-email",
3
- "version": "5.1.1",
3
+ "version": "5.1.3",
4
4
  "description": "Modular email package with SMTP, SendGrid, and Mailgun providers",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -79,19 +79,19 @@
79
79
  }
80
80
  },
81
81
  "peerDependencies": {
82
- "@nestjs/common": "^10.0.0 || ^11.0.0",
83
- "@nestjs/config": "^3.0.0 || ^4.0.0",
84
- "@nestjs/core": "^10.0.0 || ^11.0.0",
85
- "@nestjs/platform-express": "^10.0.0 || ^11.0.0",
86
- "@nestjs/swagger": "^7.0.0 || ^11.0.0",
87
- "@nestjs/typeorm": "^10.0.0 || ^11.0.0",
88
- "class-transformer": "^0.5.0",
89
- "class-validator": "^0.14.0",
82
+ "@nestjs/common": "^11.0.0",
83
+ "@nestjs/config": "^4.0.0",
84
+ "@nestjs/core": "^11.0.0",
85
+ "@nestjs/platform-express": "^11.0.0",
86
+ "@nestjs/swagger": "^11.0.0",
87
+ "@nestjs/typeorm": "^11.0.0",
88
+ "class-transformer": "^0.5.1",
89
+ "class-validator": "^0.14.0 || ^0.15.0",
90
90
  "typeorm": "^0.3.0",
91
- "nodemailer": "^7.0.0",
91
+ "nodemailer": "^7.0.0 || ^8.0.0",
92
92
  "@sendgrid/mail": "^8.0.0",
93
93
  "mailgun.js": "^10.0.0",
94
- "express": "^4.18.0"
94
+ "express": "^4.18.0 || ^5.0.0"
95
95
  },
96
96
  "peerDependenciesMeta": {
97
97
  "nodemailer": {
@@ -105,7 +105,7 @@
105
105
  }
106
106
  },
107
107
  "dependencies": {
108
- "@flusys/nestjs-core": "5.1.1",
109
- "@flusys/nestjs-shared": "5.1.1"
108
+ "@flusys/nestjs-core": "5.1.3",
109
+ "@flusys/nestjs-shared": "5.1.3"
110
110
  }
111
111
  }
@@ -15,6 +15,4 @@ export declare class EmailDataSourceProvider extends MultiTenantDataSourceServic
15
15
  private static buildParentOptions;
16
16
  getEnableCompanyFeatureForTenant(tenant?: ITenantDatabaseConfig): boolean;
17
17
  protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
18
- protected getSingleDataSource(): Promise<DataSource>;
19
- protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
20
18
  }
@@ -1,4 +1,4 @@
1
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
1
+ import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
2
2
  import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
3
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
4
  import { UtilsService } from '@flusys/nestjs-shared/modules';
@@ -8,14 +8,12 @@ import { EmailConfig, EmailConfigBase } from '../entities';
8
8
  import { IEmailConfig } from '../interfaces';
9
9
  import { EmailConfigService } from './email-config.service';
10
10
  import { EmailDataSourceProvider } from './email-datasource.provider';
11
- export declare class EmailProviderConfigService extends RequestScopedApiService<CreateEmailConfigDto, UpdateEmailConfigDto, IEmailConfig, EmailConfigBase> {
11
+ export declare class EmailProviderConfigService extends ApiService<CreateEmailConfigDto, UpdateEmailConfigDto, IEmailConfig, EmailConfigBase> {
12
12
  protected cacheManager: HybridCache;
13
13
  protected utilsService: UtilsService;
14
14
  private readonly emailConfig;
15
- private readonly dataSourceProvider;
16
15
  constructor(cacheManager: HybridCache, utilsService: UtilsService, emailConfig: EmailConfigService, dataSourceProvider: EmailDataSourceProvider);
17
16
  protected resolveEntity(): EntityTarget<EmailConfigBase>;
18
- protected getDataSourceProvider(): EmailDataSourceProvider;
19
17
  convertSingleDtoToEntity(dto: CreateEmailConfigDto | UpdateEmailConfigDto, user: ILoggedUserInfo | null): Promise<EmailConfigBase>;
20
18
  getSelectQuery(query: SelectQueryBuilder<EmailConfigBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
21
19
  query: SelectQueryBuilder<EmailConfig>;
@@ -1,4 +1,4 @@
1
- import { HybridCache, RequestScopedApiService } from '@flusys/nestjs-shared/classes';
1
+ import { HybridCache, ApiService } from '@flusys/nestjs-shared/classes';
2
2
  import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
3
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
4
  import { UtilsService } from '@flusys/nestjs-shared/modules';
@@ -8,14 +8,12 @@ import { EmailTemplate, EmailTemplateBase } from '../entities';
8
8
  import { IEmailTemplate } from '../interfaces';
9
9
  import { EmailConfigService } from './email-config.service';
10
10
  import { EmailDataSourceProvider } from './email-datasource.provider';
11
- export declare class EmailTemplateService extends RequestScopedApiService<CreateEmailTemplateDto, UpdateEmailTemplateDto, IEmailTemplate, EmailTemplateBase> {
11
+ export declare class EmailTemplateService extends ApiService<CreateEmailTemplateDto, UpdateEmailTemplateDto, IEmailTemplate, EmailTemplateBase> {
12
12
  protected cacheManager: HybridCache;
13
13
  protected utilsService: UtilsService;
14
14
  private readonly emailConfig;
15
- private readonly dataSourceProvider;
16
15
  constructor(cacheManager: HybridCache, utilsService: UtilsService, emailConfig: EmailConfigService, dataSourceProvider: EmailDataSourceProvider);
17
16
  protected resolveEntity(): EntityTarget<EmailTemplateBase>;
18
- protected getDataSourceProvider(): EmailDataSourceProvider;
19
17
  convertSingleDtoToEntity(dto: CreateEmailTemplateDto | UpdateEmailTemplateDto, user: ILoggedUserInfo | null): Promise<EmailTemplateBase>;
20
18
  getSelectQuery(query: SelectQueryBuilder<EmailTemplateBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
21
19
  query: SelectQueryBuilder<EmailTemplate>;