@flusys/nestjs-email 1.1.0-beta

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 (124) hide show
  1. package/cjs/config/email-config.service.js +94 -0
  2. package/cjs/config/email.constants.js +40 -0
  3. package/cjs/config/index.js +19 -0
  4. package/cjs/controllers/email-config.controller.js +59 -0
  5. package/cjs/controllers/email-send.controller.js +142 -0
  6. package/cjs/controllers/email-template.controller.js +84 -0
  7. package/cjs/controllers/index.js +20 -0
  8. package/cjs/docs/email-swagger.config.js +176 -0
  9. package/cjs/docs/index.js +11 -0
  10. package/cjs/dtos/email-config.dto.js +238 -0
  11. package/cjs/dtos/email-send.dto.js +376 -0
  12. package/cjs/dtos/email-template.dto.js +283 -0
  13. package/cjs/dtos/index.js +20 -0
  14. package/cjs/entities/email-config-base.entity.js +111 -0
  15. package/cjs/entities/email-config-with-company.entity.js +63 -0
  16. package/cjs/entities/email-config.entity.js +25 -0
  17. package/cjs/entities/email-template-base.entity.js +134 -0
  18. package/cjs/entities/email-template-with-company.entity.js +63 -0
  19. package/cjs/entities/email-template.entity.js +25 -0
  20. package/cjs/entities/index.js +41 -0
  21. package/cjs/enums/email-provider-type.enum.js +18 -0
  22. package/cjs/enums/index.js +18 -0
  23. package/cjs/index.js +27 -0
  24. package/cjs/interfaces/email-config.interface.js +4 -0
  25. package/cjs/interfaces/email-module-options.interface.js +4 -0
  26. package/cjs/interfaces/email-provider.interface.js +6 -0
  27. package/cjs/interfaces/email-template.interface.js +4 -0
  28. package/cjs/interfaces/index.js +21 -0
  29. package/cjs/modules/email.module.js +177 -0
  30. package/cjs/modules/index.js +18 -0
  31. package/cjs/providers/email-factory.service.js +160 -0
  32. package/cjs/providers/email-provider.registry.js +51 -0
  33. package/cjs/providers/index.js +22 -0
  34. package/cjs/providers/mailgun-provider.js +125 -0
  35. package/cjs/providers/sendgrid-provider.js +156 -0
  36. package/cjs/providers/smtp-provider.js +185 -0
  37. package/cjs/services/email-datasource.provider.js +215 -0
  38. package/cjs/services/email-provider-config.service.js +180 -0
  39. package/cjs/services/email-send.service.js +228 -0
  40. package/cjs/services/email-template.service.js +186 -0
  41. package/cjs/services/index.js +21 -0
  42. package/config/email-config.service.d.ts +13 -0
  43. package/config/email.constants.d.ts +11 -0
  44. package/config/index.d.ts +2 -0
  45. package/controllers/email-config.controller.d.ts +17 -0
  46. package/controllers/email-send.controller.d.ts +19 -0
  47. package/controllers/email-template.controller.d.ts +25 -0
  48. package/controllers/index.d.ts +3 -0
  49. package/docs/email-swagger.config.d.ts +3 -0
  50. package/docs/index.d.ts +1 -0
  51. package/dtos/email-config.dto.d.ts +33 -0
  52. package/dtos/email-send.dto.d.ts +45 -0
  53. package/dtos/email-template.dto.d.ts +42 -0
  54. package/dtos/index.d.ts +3 -0
  55. package/entities/email-config-base.entity.d.ts +11 -0
  56. package/entities/email-config-with-company.entity.d.ts +4 -0
  57. package/entities/email-config.entity.d.ts +3 -0
  58. package/entities/email-template-base.entity.d.ts +14 -0
  59. package/entities/email-template-with-company.entity.d.ts +4 -0
  60. package/entities/email-template.entity.d.ts +3 -0
  61. package/entities/index.d.ts +7 -0
  62. package/enums/email-provider-type.enum.d.ts +5 -0
  63. package/enums/index.d.ts +1 -0
  64. package/fesm/config/email-config.service.js +84 -0
  65. package/fesm/config/email.constants.js +13 -0
  66. package/fesm/config/index.js +2 -0
  67. package/fesm/controllers/email-config.controller.js +49 -0
  68. package/fesm/controllers/email-send.controller.js +132 -0
  69. package/fesm/controllers/email-template.controller.js +74 -0
  70. package/fesm/controllers/index.js +3 -0
  71. package/fesm/docs/email-swagger.config.js +172 -0
  72. package/fesm/docs/index.js +1 -0
  73. package/fesm/dtos/email-config.dto.js +223 -0
  74. package/fesm/dtos/email-send.dto.js +360 -0
  75. package/fesm/dtos/email-template.dto.js +268 -0
  76. package/fesm/dtos/index.js +3 -0
  77. package/fesm/entities/email-config-base.entity.js +101 -0
  78. package/fesm/entities/email-config-with-company.entity.js +53 -0
  79. package/fesm/entities/email-config.entity.js +15 -0
  80. package/fesm/entities/email-template-base.entity.js +124 -0
  81. package/fesm/entities/email-template-with-company.entity.js +53 -0
  82. package/fesm/entities/email-template.entity.js +15 -0
  83. package/fesm/entities/index.js +20 -0
  84. package/fesm/enums/email-provider-type.enum.js +8 -0
  85. package/fesm/enums/index.js +1 -0
  86. package/fesm/index.js +10 -0
  87. package/fesm/interfaces/email-config.interface.js +3 -0
  88. package/fesm/interfaces/email-module-options.interface.js +3 -0
  89. package/fesm/interfaces/email-provider.interface.js +5 -0
  90. package/fesm/interfaces/email-template.interface.js +3 -0
  91. package/fesm/interfaces/index.js +4 -0
  92. package/fesm/modules/email.module.js +167 -0
  93. package/fesm/modules/index.js +1 -0
  94. package/fesm/providers/email-factory.service.js +109 -0
  95. package/fesm/providers/email-provider.registry.js +44 -0
  96. package/fesm/providers/index.js +5 -0
  97. package/fesm/providers/mailgun-provider.js +119 -0
  98. package/fesm/providers/sendgrid-provider.js +150 -0
  99. package/fesm/providers/smtp-provider.js +137 -0
  100. package/fesm/services/email-datasource.provider.js +164 -0
  101. package/fesm/services/email-provider-config.service.js +170 -0
  102. package/fesm/services/email-send.service.js +218 -0
  103. package/fesm/services/email-template.service.js +176 -0
  104. package/fesm/services/index.js +4 -0
  105. package/index.d.ts +9 -0
  106. package/interfaces/email-config.interface.d.ts +28 -0
  107. package/interfaces/email-module-options.interface.d.ts +26 -0
  108. package/interfaces/email-provider.interface.d.ts +34 -0
  109. package/interfaces/email-template.interface.d.ts +64 -0
  110. package/interfaces/index.d.ts +4 -0
  111. package/modules/email.module.d.ts +9 -0
  112. package/modules/index.d.ts +1 -0
  113. package/package.json +105 -0
  114. package/providers/email-factory.service.d.ts +14 -0
  115. package/providers/email-provider.registry.d.ts +10 -0
  116. package/providers/index.d.ts +5 -0
  117. package/providers/mailgun-provider.d.ts +11 -0
  118. package/providers/sendgrid-provider.d.ts +11 -0
  119. package/providers/smtp-provider.d.ts +11 -0
  120. package/services/email-datasource.provider.d.ts +25 -0
  121. package/services/email-provider-config.service.d.ts +32 -0
  122. package/services/email-send.service.d.ts +20 -0
  123. package/services/email-template.service.d.ts +31 -0
  124. package/services/index.d.ts +4 -0
@@ -0,0 +1,176 @@
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 { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
29
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
30
+ import { Inject, Injectable, Scope } from '@nestjs/common';
31
+ import { EmailConfigService } from '../config';
32
+ import { EmailTemplate, EmailTemplateWithCompany } from '../entities';
33
+ import { EmailDataSourceProvider } from './email-datasource.provider';
34
+ export class EmailTemplateService extends RequestScopedApiService {
35
+ /**
36
+ * Resolve entity class for this service
37
+ */ resolveEntity() {
38
+ const enableCompanyFeature = this.emailConfig.isCompanyFeatureEnabled();
39
+ return enableCompanyFeature ? EmailTemplateWithCompany : EmailTemplate;
40
+ }
41
+ /**
42
+ * Get DataSource provider for this service
43
+ */ getDataSourceProvider() {
44
+ return this.dataSourceProvider;
45
+ }
46
+ async convertSingleDtoToEntity(dto, user) {
47
+ // For updates, fetch existing template to handle versioning
48
+ const updateDto = dto;
49
+ if (updateDto.id) {
50
+ await this.ensureRepositoryInitialized();
51
+ const existing = await this.repository.findOne({
52
+ where: {
53
+ id: updateDto.id
54
+ }
55
+ });
56
+ if (existing) {
57
+ // Auto-increment schema version if schema changed
58
+ if (dto.schema && JSON.stringify(dto.schema) !== JSON.stringify(existing.schema)) {
59
+ dto.schemaVersion = existing.schemaVersion + 1;
60
+ this.logger.log(`Schema changed for template ${updateDto.id}, incrementing version from ${existing.schemaVersion} to ${dto.schemaVersion}`);
61
+ }
62
+ }
63
+ }
64
+ let templateEntity = {
65
+ ...dto
66
+ };
67
+ // Set company fields if company feature is enabled
68
+ if (this.emailConfig.isCompanyFeatureEnabled()) {
69
+ templateEntity.companyId = user?.companyId ?? null;
70
+ }
71
+ return templateEntity;
72
+ }
73
+ async getSelectQuery(query, _user, select) {
74
+ if (!select || !select.length) {
75
+ select = [
76
+ 'id',
77
+ 'name',
78
+ 'slug',
79
+ 'description',
80
+ 'subject',
81
+ 'schema',
82
+ 'htmlContent',
83
+ 'textContent',
84
+ 'schemaVersion',
85
+ 'isActive',
86
+ 'isHtml',
87
+ 'metadata',
88
+ 'createdAt',
89
+ 'updatedAt'
90
+ ];
91
+ if (this.emailConfig.isCompanyFeatureEnabled()) {
92
+ select.push('companyId');
93
+ }
94
+ }
95
+ const selectFields = select.map((field)=>`${this.entityName}.${field}`);
96
+ query.select(selectFields);
97
+ return {
98
+ query,
99
+ isRaw: false
100
+ };
101
+ }
102
+ /**
103
+ * Override: Extra query manipulation - Auto-filter by user's company
104
+ */ async getExtraManipulateQuery(query, filterDto, user) {
105
+ const result = await super.getExtraManipulateQuery(query, filterDto, user);
106
+ const enableCompanyFeature = this.emailConfig.isCompanyFeatureEnabled();
107
+ if (enableCompanyFeature && user?.companyId) {
108
+ query.andWhere('emailTemplate.companyId = :companyId', {
109
+ companyId: user.companyId
110
+ });
111
+ }
112
+ query.orderBy(`${this.entityName}.createdAt`, 'DESC');
113
+ return result;
114
+ }
115
+ /**
116
+ * Find template by ID directly (bypasses company filtering)
117
+ */ async findByIdDirect(id) {
118
+ await this.ensureRepositoryInitialized();
119
+ return await this.repository.findOne({
120
+ where: {
121
+ id
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * Find template by slug (scoped to user's company if enabled)
127
+ */ async findBySlug(slug, user) {
128
+ await this.ensureRepositoryInitialized();
129
+ const where = {
130
+ slug,
131
+ isActive: true
132
+ };
133
+ if (this.emailConfig.isCompanyFeatureEnabled() && user?.companyId) {
134
+ where.companyId = user.companyId;
135
+ }
136
+ return await this.repository.findOne({
137
+ where
138
+ });
139
+ }
140
+ /**
141
+ * Get all active templates (scoped to user's company if enabled)
142
+ */ async getActiveTemplates(user) {
143
+ await this.ensureRepositoryInitialized();
144
+ const where = {
145
+ isActive: true
146
+ };
147
+ if (this.emailConfig.isCompanyFeatureEnabled() && user?.companyId) {
148
+ where.companyId = user.companyId;
149
+ }
150
+ return await this.repository.find({
151
+ where,
152
+ order: {
153
+ name: 'ASC'
154
+ }
155
+ });
156
+ }
157
+ constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
158
+ super('emailTemplate', null, cacheManager, utilsService, EmailTemplateService.name, true), _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;
159
+ }
160
+ }
161
+ EmailTemplateService = _ts_decorate([
162
+ Injectable({
163
+ scope: Scope.REQUEST
164
+ }),
165
+ _ts_param(0, Inject('CACHE_INSTANCE')),
166
+ _ts_param(1, Inject(UtilsService)),
167
+ _ts_param(2, Inject(EmailConfigService)),
168
+ _ts_param(3, Inject(EmailDataSourceProvider)),
169
+ _ts_metadata("design:type", Function),
170
+ _ts_metadata("design:paramtypes", [
171
+ typeof HybridCache === "undefined" ? Object : HybridCache,
172
+ typeof UtilsService === "undefined" ? Object : UtilsService,
173
+ typeof EmailConfigService === "undefined" ? Object : EmailConfigService,
174
+ typeof EmailDataSourceProvider === "undefined" ? Object : EmailDataSourceProvider
175
+ ])
176
+ ], EmailTemplateService);
@@ -0,0 +1,4 @@
1
+ export * from './email-datasource.provider';
2
+ export * from './email-provider-config.service';
3
+ export * from './email-template.service';
4
+ export * from './email-send.service';
package/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export * from './controllers';
2
+ export * from './services';
3
+ export * from './entities';
4
+ export * from './modules';
5
+ export * from './config';
6
+ export * from './dtos';
7
+ export * from './enums';
8
+ export * from './interfaces';
9
+ export * from './providers';
@@ -0,0 +1,28 @@
1
+ import { IIdentity } from '@flusys/nestjs-shared/interfaces';
2
+ import { EmailProviderTypeEnum } from '../enums';
3
+ export interface IEmailConfig extends IIdentity {
4
+ name: string;
5
+ provider: EmailProviderTypeEnum;
6
+ config: Record<string, any>;
7
+ fromEmail: string | null;
8
+ fromName: string | null;
9
+ isActive: boolean;
10
+ companyId?: string | null;
11
+ }
12
+ export interface ISmtpConfig {
13
+ host: string;
14
+ port: number;
15
+ secure?: boolean;
16
+ auth?: {
17
+ user: string;
18
+ pass: string;
19
+ };
20
+ }
21
+ export interface ISendGridConfig {
22
+ apiKey: string;
23
+ }
24
+ export interface IMailgunConfig {
25
+ apiKey: string;
26
+ domain: string;
27
+ region?: 'us' | 'eu';
28
+ }
@@ -0,0 +1,26 @@
1
+ import { IBootstrapAppConfig, IDataSourceServiceOptions, IDynamicModuleConfig, IModuleOptionsFactory } from '@flusys/nestjs-core';
2
+ import { ModuleMetadata, Type } from '@nestjs/common';
3
+ export interface IEmailModuleConfig extends IDataSourceServiceOptions {
4
+ defaultProvider?: string;
5
+ rateLimitPerMinute?: number;
6
+ enableLogging?: boolean;
7
+ }
8
+ export interface IEmailModuleConfigFull {
9
+ bootstrapAppConfig?: IBootstrapAppConfig;
10
+ config?: IEmailModuleConfig;
11
+ }
12
+ export interface EmailModuleOptions extends IDynamicModuleConfig {
13
+ bootstrapAppConfig?: IBootstrapAppConfig;
14
+ config?: IEmailModuleConfig;
15
+ }
16
+ export interface EmailOptionsFactory extends IModuleOptionsFactory<IEmailModuleConfig> {
17
+ createEmailOptions(): Promise<IEmailModuleConfig> | IEmailModuleConfig;
18
+ createOptions(): Promise<IEmailModuleConfig> | IEmailModuleConfig;
19
+ }
20
+ export interface EmailModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'>, IDynamicModuleConfig {
21
+ bootstrapAppConfig: IBootstrapAppConfig;
22
+ useFactory?: (...args: any[]) => Promise<IEmailModuleConfig> | IEmailModuleConfig;
23
+ inject?: any[];
24
+ useClass?: Type<EmailOptionsFactory>;
25
+ useExisting?: Type<EmailOptionsFactory>;
26
+ }
@@ -0,0 +1,34 @@
1
+ export interface IEmailProviderConfig {
2
+ provider: string;
3
+ config: Record<string, any>;
4
+ }
5
+ export interface IEmailAttachment {
6
+ filename: string;
7
+ content: Buffer | string;
8
+ contentType?: string;
9
+ encoding?: string;
10
+ }
11
+ export interface IEmailSendOptions {
12
+ to: string | string[];
13
+ cc?: string | string[];
14
+ bcc?: string | string[];
15
+ subject: string;
16
+ html?: string;
17
+ text?: string;
18
+ from?: string;
19
+ fromName?: string;
20
+ replyTo?: string;
21
+ attachments?: IEmailAttachment[];
22
+ }
23
+ export interface IEmailSendResult {
24
+ success: boolean;
25
+ messageId?: string;
26
+ error?: string;
27
+ }
28
+ export interface IEmailProvider {
29
+ sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
30
+ sendBulkEmails(options: IEmailSendOptions[]): Promise<IEmailSendResult[]>;
31
+ healthCheck(): Promise<boolean>;
32
+ initialize?(config: any): Promise<void>;
33
+ close?(): Promise<void>;
34
+ }
@@ -0,0 +1,64 @@
1
+ import { IIdentity } from '@flusys/nestjs-shared/interfaces';
2
+ export interface IEmailTemplateVariable {
3
+ name: string;
4
+ type: 'string' | 'number' | 'boolean' | 'date';
5
+ required?: boolean;
6
+ defaultValue?: string;
7
+ description?: string;
8
+ }
9
+ export interface IEmailTemplate extends IIdentity {
10
+ name: string;
11
+ slug: string;
12
+ description: string | null;
13
+ subject: string;
14
+ schema: Record<string, unknown>;
15
+ htmlContent: string;
16
+ textContent: string | null;
17
+ schemaVersion: number;
18
+ isActive: boolean;
19
+ isHtml: boolean;
20
+ metadata: Record<string, unknown> | null;
21
+ companyId?: string | null;
22
+ }
23
+ export interface IEmailSection {
24
+ id: string;
25
+ type: 'header' | 'body' | 'footer';
26
+ name: string;
27
+ blocks: IEmailBlock[];
28
+ order: number;
29
+ style?: IEmailSectionStyle;
30
+ }
31
+ export interface IEmailSectionStyle {
32
+ backgroundColor?: string;
33
+ padding?: string;
34
+ maxWidth?: string;
35
+ }
36
+ export interface IEmailBlock {
37
+ id: string;
38
+ type: 'text' | 'image' | 'button' | 'divider' | 'html';
39
+ order: number;
40
+ content: Record<string, any>;
41
+ style?: IEmailBlockStyle;
42
+ }
43
+ export interface IEmailBlockStyle {
44
+ textAlign?: 'left' | 'center' | 'right';
45
+ padding?: string;
46
+ margin?: string;
47
+ backgroundColor?: string;
48
+ }
49
+ export interface IEmailSettings {
50
+ maxWidth?: string;
51
+ backgroundColor?: string;
52
+ fontFamily?: string;
53
+ baseTextColor?: string;
54
+ }
55
+ export interface IEmailSchema {
56
+ id: string;
57
+ version: string;
58
+ name: string;
59
+ subject: string;
60
+ preheader?: string;
61
+ sections: IEmailSection[];
62
+ variables?: IEmailTemplateVariable[];
63
+ settings?: IEmailSettings;
64
+ }
@@ -0,0 +1,4 @@
1
+ export * from './email-provider.interface';
2
+ export * from './email-module-options.interface';
3
+ export * from './email-config.interface';
4
+ export * from './email-template.interface';
@@ -0,0 +1,9 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { EmailModuleAsyncOptions, EmailModuleOptions } from '../interfaces';
3
+ export declare class EmailModule {
4
+ static forRoot(options: EmailModuleOptions): DynamicModule;
5
+ static forRootAsync(options: EmailModuleAsyncOptions): DynamicModule;
6
+ private static getControllers;
7
+ private static getProviders;
8
+ private static createAsyncProviders;
9
+ }
@@ -0,0 +1 @@
1
+ export * from './email.module';
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@flusys/nestjs-email",
3
+ "version": "1.1.0-beta",
4
+ "description": "Modular email package with SMTP, SendGrid, and Mailgun providers",
5
+ "main": "cjs/index.js",
6
+ "module": "fesm/index.js",
7
+ "types": "index.d.ts",
8
+ "sideEffects": false,
9
+ "keywords": [
10
+ "nestjs",
11
+ "email",
12
+ "smtp",
13
+ "sendgrid",
14
+ "mailgun",
15
+ "template",
16
+ "@flusys"
17
+ ],
18
+ "license": "UNLICENSED",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./index.d.ts",
22
+ "import": "./fesm/index.js",
23
+ "require": "./cjs/index.js"
24
+ },
25
+ "./config": {
26
+ "types": "./config/index.d.ts",
27
+ "import": "./fesm/config/index.js",
28
+ "require": "./cjs/config/index.js"
29
+ },
30
+ "./controllers": {
31
+ "types": "./controllers/index.d.ts",
32
+ "import": "./fesm/controllers/index.js",
33
+ "require": "./cjs/controllers/index.js"
34
+ },
35
+ "./dtos": {
36
+ "types": "./dtos/index.d.ts",
37
+ "import": "./fesm/dtos/index.js",
38
+ "require": "./cjs/dtos/index.js"
39
+ },
40
+ "./entities": {
41
+ "types": "./entities/index.d.ts",
42
+ "import": "./fesm/entities/index.js",
43
+ "require": "./cjs/entities/index.js"
44
+ },
45
+ "./enums": {
46
+ "types": "./enums/index.d.ts",
47
+ "import": "./fesm/enums/index.js",
48
+ "require": "./cjs/enums/index.js"
49
+ },
50
+ "./interfaces": {
51
+ "types": "./interfaces/index.d.ts",
52
+ "import": "./fesm/interfaces/index.js",
53
+ "require": "./cjs/interfaces/index.js"
54
+ },
55
+ "./modules": {
56
+ "types": "./modules/index.d.ts",
57
+ "import": "./fesm/modules/index.js",
58
+ "require": "./cjs/modules/index.js"
59
+ },
60
+ "./providers": {
61
+ "types": "./providers/index.d.ts",
62
+ "import": "./fesm/providers/index.js",
63
+ "require": "./cjs/providers/index.js"
64
+ },
65
+ "./services": {
66
+ "types": "./services/index.d.ts",
67
+ "import": "./fesm/services/index.js",
68
+ "require": "./cjs/services/index.js"
69
+ },
70
+ "./*": {
71
+ "types": "./*.d.ts",
72
+ "import": "./*.js",
73
+ "require": "./*.js"
74
+ }
75
+ },
76
+ "peerDependencies": {
77
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
78
+ "@nestjs/config": "^3.0.0 || ^4.0.0",
79
+ "@nestjs/core": "^10.0.0 || ^11.0.0",
80
+ "@nestjs/platform-express": "^10.0.0 || ^11.0.0",
81
+ "@nestjs/swagger": "^7.0.0 || ^11.0.0",
82
+ "@nestjs/typeorm": "^10.0.0 || ^11.0.0",
83
+ "class-transformer": "^0.5.0",
84
+ "class-validator": "^0.14.0",
85
+ "typeorm": "^0.3.0",
86
+ "nodemailer": "^6.9.0",
87
+ "@sendgrid/mail": "^8.0.0",
88
+ "mailgun.js": "^10.0.0"
89
+ },
90
+ "peerDependenciesMeta": {
91
+ "nodemailer": {
92
+ "optional": false
93
+ },
94
+ "@sendgrid/mail": {
95
+ "optional": true
96
+ },
97
+ "mailgun.js": {
98
+ "optional": true
99
+ }
100
+ },
101
+ "dependencies": {
102
+ "@flusys/nestjs-core": "1.1.0-beta",
103
+ "@flusys/nestjs-shared": "1.1.0-beta"
104
+ }
105
+ }
@@ -0,0 +1,14 @@
1
+ import { OnModuleDestroy } from '@nestjs/common';
2
+ import { EmailConfigService } from '../config/email-config.service';
3
+ import { IEmailProvider, IEmailProviderConfig } from '../interfaces';
4
+ export declare class EmailFactoryService implements OnModuleDestroy {
5
+ private readonly emailConfigService;
6
+ private readonly logger;
7
+ private providerCache;
8
+ constructor(emailConfigService: EmailConfigService);
9
+ private generateCacheKey;
10
+ createProvider(config: IEmailProviderConfig): Promise<IEmailProvider>;
11
+ isProviderAvailable(providerName: string): boolean;
12
+ getAvailableProviders(): string[];
13
+ onModuleDestroy(): Promise<void>;
14
+ }
@@ -0,0 +1,10 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { IEmailProvider } from '../interfaces';
3
+ export declare class EmailProviderRegistry {
4
+ private static providers;
5
+ static register(providerName: string, providerClass: Type<IEmailProvider>): void;
6
+ static get(providerName: string): Type<IEmailProvider> | undefined;
7
+ static has(providerName: string): boolean;
8
+ static getAll(): string[];
9
+ static clear(): void;
10
+ }
@@ -0,0 +1,5 @@
1
+ export * from './email-provider.registry';
2
+ export * from './email-factory.service';
3
+ export * from './smtp-provider';
4
+ export * from './sendgrid-provider';
5
+ export * from './mailgun-provider';
@@ -0,0 +1,11 @@
1
+ import { IEmailProvider, IEmailSendOptions, IEmailSendResult, IMailgunConfig } from '../interfaces';
2
+ export declare class MailgunProvider implements IEmailProvider {
3
+ private logger;
4
+ private client;
5
+ private config;
6
+ initialize(config: IMailgunConfig): Promise<void>;
7
+ sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
8
+ sendBulkEmails(options: IEmailSendOptions[]): Promise<IEmailSendResult[]>;
9
+ healthCheck(): Promise<boolean>;
10
+ close(): Promise<void>;
11
+ }
@@ -0,0 +1,11 @@
1
+ import { IEmailProvider, IEmailSendOptions, IEmailSendResult, ISendGridConfig } from '../interfaces';
2
+ export declare class SendGridProvider implements IEmailProvider {
3
+ private logger;
4
+ private sgMail;
5
+ private config;
6
+ initialize(config: ISendGridConfig): Promise<void>;
7
+ sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
8
+ sendBulkEmails(options: IEmailSendOptions[]): Promise<IEmailSendResult[]>;
9
+ healthCheck(): Promise<boolean>;
10
+ close(): Promise<void>;
11
+ }
@@ -0,0 +1,11 @@
1
+ import { IEmailProvider, IEmailSendOptions, IEmailSendResult, ISmtpConfig } from '../interfaces';
2
+ export declare class SmtpProvider implements IEmailProvider {
3
+ private logger;
4
+ private transporter;
5
+ private config;
6
+ initialize(config: ISmtpConfig): Promise<void>;
7
+ sendEmail(options: IEmailSendOptions): Promise<IEmailSendResult>;
8
+ sendBulkEmails(options: IEmailSendOptions[]): Promise<IEmailSendResult[]>;
9
+ healthCheck(): Promise<boolean>;
10
+ close(): Promise<void>;
11
+ }
@@ -0,0 +1,25 @@
1
+ import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
2
+ import { IDatabaseConfig, ITenantDatabaseConfig } from '@flusys/nestjs-core';
3
+ import { Logger } from '@nestjs/common';
4
+ import { Request } from 'express';
5
+ import { DataSource } from 'typeorm';
6
+ import { EmailModuleOptions } from '../interfaces';
7
+ export declare class EmailDataSourceProvider extends MultiTenantDataSourceService {
8
+ private readonly emailOptions;
9
+ protected readonly logger: Logger;
10
+ protected static readonly tenantConnections: Map<string, DataSource>;
11
+ protected static singleDataSource: DataSource | null;
12
+ protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
13
+ protected static initialized: boolean;
14
+ protected static readonly connectionLocks: Map<string, Promise<DataSource>>;
15
+ protected static singleConnectionLock: Promise<DataSource> | null;
16
+ constructor(emailOptions: EmailModuleOptions, request?: Request);
17
+ private static buildParentOptions;
18
+ getEnableCompanyFeature(): boolean;
19
+ getEnableCompanyFeatureForTenant(tenant?: ITenantDatabaseConfig): boolean;
20
+ getEnableCompanyFeatureForCurrentTenant(): boolean;
21
+ getEmailEntities(enableCompanyFeature?: boolean): Promise<any[]>;
22
+ protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
23
+ protected getSingleDataSource(): Promise<DataSource>;
24
+ protected getOrCreateTenantConnection(tenant: ITenantDatabaseConfig): Promise<DataSource>;
25
+ }
@@ -0,0 +1,32 @@
1
+ import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
+ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
+ import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
5
+ import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
6
+ import { EmailConfigService } from '../config';
7
+ import { CreateEmailConfigDto, UpdateEmailConfigDto } from '../dtos';
8
+ import { EmailConfigBase } from '../entities';
9
+ import { EmailProviderTypeEnum } from '../enums';
10
+ import { IEmailConfig } from '../interfaces';
11
+ import { EmailDataSourceProvider } from './email-datasource.provider';
12
+ export declare class EmailProviderConfigService extends RequestScopedApiService<CreateEmailConfigDto, UpdateEmailConfigDto, IEmailConfig, EmailConfigBase, Repository<EmailConfigBase>> {
13
+ protected cacheManager: HybridCache;
14
+ protected utilsService: UtilsService;
15
+ private readonly emailConfig;
16
+ private readonly dataSourceProvider;
17
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, emailConfig: EmailConfigService, dataSourceProvider: EmailDataSourceProvider);
18
+ protected resolveEntity(): EntityTarget<EmailConfigBase>;
19
+ protected getDataSourceProvider(): EmailDataSourceProvider;
20
+ convertSingleDtoToEntity(dto: CreateEmailConfigDto | UpdateEmailConfigDto, user: ILoggedUserInfo | null): Promise<EmailConfigBase>;
21
+ getSelectQuery(query: SelectQueryBuilder<EmailConfigBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
22
+ query: SelectQueryBuilder<EmailConfigBase>;
23
+ isRaw: boolean;
24
+ }>;
25
+ protected getExtraManipulateQuery(query: SelectQueryBuilder<EmailConfigBase>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
26
+ query: SelectQueryBuilder<EmailConfigBase>;
27
+ isRaw: boolean;
28
+ }>;
29
+ findByIdDirect(id: string): Promise<EmailConfigBase | null>;
30
+ getDefaultConfig(user?: ILoggedUserInfo): Promise<EmailConfigBase | null>;
31
+ getConfigByProvider(provider: EmailProviderTypeEnum, user?: ILoggedUserInfo): Promise<EmailConfigBase[]>;
32
+ }
@@ -0,0 +1,20 @@
1
+ import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
2
+ import { EmailConfigService } from '../config';
3
+ import { SendEmailDto, SendTemplateEmailDto } from '../dtos';
4
+ import { IEmailSendResult } from '../interfaces';
5
+ import { EmailFactoryService } from '../providers';
6
+ import { EmailProviderConfigService } from './email-provider-config.service';
7
+ import { EmailTemplateService } from './email-template.service';
8
+ export declare class EmailSendService {
9
+ private readonly emailFactory;
10
+ private readonly emailConfigService;
11
+ private readonly emailProviderConfigService;
12
+ private readonly emailTemplateService;
13
+ private readonly logger;
14
+ constructor(emailFactory: EmailFactoryService, emailConfigService: EmailConfigService, emailProviderConfigService: EmailProviderConfigService, emailTemplateService: EmailTemplateService);
15
+ private getEmailProviderWithConfig;
16
+ private interpolateVariables;
17
+ sendEmail(dto: SendEmailDto, user?: ILoggedUserInfo): Promise<IEmailSendResult>;
18
+ sendTemplateEmail(dto: SendTemplateEmailDto, user?: ILoggedUserInfo): Promise<IEmailSendResult>;
19
+ sendTestEmail(emailConfigId: string, recipient: string, user?: ILoggedUserInfo): Promise<IEmailSendResult>;
20
+ }
@@ -0,0 +1,31 @@
1
+ import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
+ import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
+ import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
5
+ import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
6
+ import { EmailConfigService } from '../config';
7
+ import { CreateEmailTemplateDto, UpdateEmailTemplateDto } from '../dtos';
8
+ import { EmailTemplateBase } from '../entities';
9
+ import { IEmailTemplate } from '../interfaces';
10
+ import { EmailDataSourceProvider } from './email-datasource.provider';
11
+ export declare class EmailTemplateService extends RequestScopedApiService<CreateEmailTemplateDto, UpdateEmailTemplateDto, IEmailTemplate, EmailTemplateBase, Repository<EmailTemplateBase>> {
12
+ protected cacheManager: HybridCache;
13
+ protected utilsService: UtilsService;
14
+ private readonly emailConfig;
15
+ private readonly dataSourceProvider;
16
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, emailConfig: EmailConfigService, dataSourceProvider: EmailDataSourceProvider);
17
+ protected resolveEntity(): EntityTarget<EmailTemplateBase>;
18
+ protected getDataSourceProvider(): EmailDataSourceProvider;
19
+ convertSingleDtoToEntity(dto: CreateEmailTemplateDto | UpdateEmailTemplateDto, user: ILoggedUserInfo | null): Promise<EmailTemplateBase>;
20
+ getSelectQuery(query: SelectQueryBuilder<EmailTemplateBase>, _user: ILoggedUserInfo | null, select?: string[]): Promise<{
21
+ query: SelectQueryBuilder<EmailTemplateBase>;
22
+ isRaw: boolean;
23
+ }>;
24
+ protected getExtraManipulateQuery(query: SelectQueryBuilder<EmailTemplateBase>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
25
+ query: SelectQueryBuilder<EmailTemplateBase>;
26
+ isRaw: boolean;
27
+ }>;
28
+ findByIdDirect(id: string): Promise<EmailTemplateBase | null>;
29
+ findBySlug(slug: string, user?: ILoggedUserInfo): Promise<EmailTemplateBase | null>;
30
+ getActiveTemplates(user?: ILoggedUserInfo): Promise<EmailTemplateBase[]>;
31
+ }
@@ -0,0 +1,4 @@
1
+ export * from './email-datasource.provider';
2
+ export * from './email-provider-config.service';
3
+ export * from './email-template.service';
4
+ export * from './email-send.service';