@open-kingdom/shared-backend-feature-email 0.0.2-10

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 (44) hide show
  1. package/.spec.swcrc +22 -0
  2. package/README.md +11 -0
  3. package/dist/index.d.ts +10 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +6 -0
  6. package/dist/lib/email.controller.d.ts +8 -0
  7. package/dist/lib/email.controller.d.ts.map +1 -0
  8. package/dist/lib/email.controller.js +53 -0
  9. package/dist/lib/email.d.ts +12 -0
  10. package/dist/lib/email.d.ts.map +1 -0
  11. package/dist/lib/email.dto.d.ts +11 -0
  12. package/dist/lib/email.dto.d.ts.map +1 -0
  13. package/dist/lib/email.dto.js +51 -0
  14. package/dist/lib/email.js +35 -0
  15. package/dist/lib/email.service.d.ts +8 -0
  16. package/dist/lib/email.service.d.ts.map +1 -0
  17. package/dist/lib/email.service.js +27 -0
  18. package/dist/lib/email.types.d.ts +15 -0
  19. package/dist/lib/email.types.d.ts.map +1 -0
  20. package/dist/lib/email.types.js +2 -0
  21. package/dist/lib/providers/gmail.provider.d.ts +15 -0
  22. package/dist/lib/providers/gmail.provider.d.ts.map +1 -0
  23. package/dist/lib/providers/gmail.provider.js +43 -0
  24. package/dist/lib/providers/index.d.ts +3 -0
  25. package/dist/lib/providers/index.d.ts.map +1 -0
  26. package/dist/lib/providers/index.js +1 -0
  27. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  28. package/jest.config.cts +20 -0
  29. package/package.json +36 -0
  30. package/src/index.ts +16 -0
  31. package/src/lib/email.controller.spec.ts +36 -0
  32. package/src/lib/email.controller.ts +40 -0
  33. package/src/lib/email.dto.ts +44 -0
  34. package/src/lib/email.service.spec.ts +52 -0
  35. package/src/lib/email.service.ts +24 -0
  36. package/src/lib/email.spec.ts +30 -0
  37. package/src/lib/email.ts +46 -0
  38. package/src/lib/email.types.ts +20 -0
  39. package/src/lib/providers/gmail.provider.spec.ts +142 -0
  40. package/src/lib/providers/gmail.provider.ts +63 -0
  41. package/src/lib/providers/index.ts +2 -0
  42. package/tsconfig.json +13 -0
  43. package/tsconfig.lib.json +29 -0
  44. package/tsconfig.spec.json +22 -0
package/.spec.swcrc ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "jsc": {
3
+ "target": "es2017",
4
+ "parser": {
5
+ "syntax": "typescript",
6
+ "decorators": true,
7
+ "dynamicImport": true
8
+ },
9
+ "transform": {
10
+ "decoratorMetadata": true,
11
+ "legacyDecorator": true
12
+ },
13
+ "keepClassNames": true,
14
+ "externalHelpers": true,
15
+ "loose": true
16
+ },
17
+ "module": {
18
+ "type": "es6"
19
+ },
20
+ "sourceMaps": true,
21
+ "exclude": []
22
+ }
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # feature-email-integration
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build feature-email-integration` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test feature-email-integration` to execute the unit tests via [Jest](https://jestjs.io).
@@ -0,0 +1,10 @@
1
+ export { EmailModule } from './lib/email.js';
2
+ export type { EmailModuleOptions } from './lib/email.js';
3
+ export { EMAIL_PROVIDER } from './lib/email.types.js';
4
+ export type { EmailProvider, EmailMessage, EmailResult, } from './lib/email.types.js';
5
+ export { EmailService } from './lib/email.service.js';
6
+ export { EmailController } from './lib/email.controller.js';
7
+ export { SendEmailDto, SendEmailResponseDto } from './lib/email.dto.js';
8
+ export { GmailProvider } from './lib/providers/index.js';
9
+ export type { GmailProviderConfig } from './lib/providers/index.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { EmailModule } from './lib/email.js';
2
+ export { EMAIL_PROVIDER } from './lib/email.types.js';
3
+ export { EmailService } from './lib/email.service.js';
4
+ export { EmailController } from './lib/email.controller.js';
5
+ export { SendEmailDto, SendEmailResponseDto } from './lib/email.dto.js';
6
+ export { GmailProvider } from './lib/providers/index.js';
@@ -0,0 +1,8 @@
1
+ import { EmailService } from './email.service.js';
2
+ import { SendEmailDto, SendEmailResponseDto } from './email.dto.js';
3
+ export declare class EmailController {
4
+ private emailService;
5
+ constructor(emailService: EmailService);
6
+ sendEmail(dto: SendEmailDto): Promise<SendEmailResponseDto>;
7
+ }
8
+ //# sourceMappingURL=email.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.controller.d.ts","sourceRoot":"","sources":["../../src/lib/email.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,qBAEa,eAAe;IAEd,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,YAAY;IA2BxC,SAAS,CAAS,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAG1E"}
@@ -0,0 +1,53 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { Controller, Post, Body } from '@nestjs/common';
3
+ import { ApiTags, ApiOperation, ApiBody, ApiResponse } from '@nestjs/swagger';
4
+ import { EmailService } from './email.service.js';
5
+ import { SendEmailDto, SendEmailResponseDto } from './email.dto.js';
6
+ let EmailController = class EmailController {
7
+ /* c8 ignore next */
8
+ constructor(emailService) {
9
+ this.emailService = emailService;
10
+ }
11
+ /* c8 ignore next */
12
+ async sendEmail(dto) {
13
+ return this.emailService.send(dto);
14
+ }
15
+ };
16
+ __decorate([
17
+ ApiOperation({
18
+ summary: 'Send test email',
19
+ description: 'Send a test email via Gmail API',
20
+ }),
21
+ ApiBody({
22
+ type: SendEmailDto,
23
+ description: 'Email details',
24
+ examples: {
25
+ test: {
26
+ summary: 'Test email',
27
+ value: {
28
+ to: 'test@example.com',
29
+ subject: 'Test Subject',
30
+ body: 'Hello, this is a test email.',
31
+ },
32
+ },
33
+ },
34
+ }),
35
+ ApiResponse({
36
+ status: 201,
37
+ description: 'Email sent successfully',
38
+ type: SendEmailResponseDto,
39
+ }),
40
+ Post('send')
41
+ /* c8 ignore next */
42
+ ,
43
+ __param(0, Body()),
44
+ __metadata("design:type", Function),
45
+ __metadata("design:paramtypes", [SendEmailDto]),
46
+ __metadata("design:returntype", Promise)
47
+ ], EmailController.prototype, "sendEmail", null);
48
+ EmailController = __decorate([
49
+ ApiTags('Email'),
50
+ Controller('email'),
51
+ __metadata("design:paramtypes", [EmailService])
52
+ ], EmailController);
53
+ export { EmailController };
@@ -0,0 +1,12 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { GmailProviderConfig } from './providers/gmail.provider.js';
3
+ export { EMAIL_PROVIDER } from './email.types.js';
4
+ export type { EmailMessage, EmailResult, EmailProvider, } from './email.types.js';
5
+ export type EmailModuleOptions = {
6
+ provider: 'gmail';
7
+ config: GmailProviderConfig;
8
+ };
9
+ export declare class EmailModule {
10
+ static forRoot(options: EmailModuleOptions): DynamicModule;
11
+ }
12
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/lib/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAEL,mBAAmB,EACpB,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAGF,qBACa,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;CAoB3D"}
@@ -0,0 +1,11 @@
1
+ export declare class SendEmailDto {
2
+ to: string;
3
+ subject: string;
4
+ body: string;
5
+ }
6
+ export declare class SendEmailResponseDto {
7
+ success: boolean;
8
+ messageId?: string;
9
+ error?: string;
10
+ }
11
+ //# sourceMappingURL=email.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.dto.d.ts","sourceRoot":"","sources":["../../src/lib/email.dto.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IAMvB,EAAE,EAAG,MAAM,CAAC;IAMZ,OAAO,EAAG,MAAM,CAAC;IAMjB,IAAI,EAAG,MAAM,CAAC;CACf;AAED,qBAAa,oBAAoB;IAK/B,OAAO,EAAG,OAAO,CAAC;IAOlB,SAAS,CAAC,EAAE,MAAM,CAAC;IAOnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,51 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { ApiProperty } from '@nestjs/swagger';
3
+ export class SendEmailDto {
4
+ }
5
+ __decorate([
6
+ ApiProperty({
7
+ description: 'Recipient email address',
8
+ example: 'recipient@example.com',
9
+ format: 'email',
10
+ }),
11
+ __metadata("design:type", String)
12
+ ], SendEmailDto.prototype, "to", void 0);
13
+ __decorate([
14
+ ApiProperty({
15
+ description: 'Email subject line',
16
+ example: 'Test Email Subject',
17
+ }),
18
+ __metadata("design:type", String)
19
+ ], SendEmailDto.prototype, "subject", void 0);
20
+ __decorate([
21
+ ApiProperty({
22
+ description: 'Email body content',
23
+ example: 'Hello, this is a test email.',
24
+ }),
25
+ __metadata("design:type", String)
26
+ ], SendEmailDto.prototype, "body", void 0);
27
+ export class SendEmailResponseDto {
28
+ }
29
+ __decorate([
30
+ ApiProperty({
31
+ description: 'Whether the email was sent successfully',
32
+ example: true,
33
+ }),
34
+ __metadata("design:type", Boolean)
35
+ ], SendEmailResponseDto.prototype, "success", void 0);
36
+ __decorate([
37
+ ApiProperty({
38
+ description: 'Gmail message ID if successful',
39
+ example: '18c1234567890abc',
40
+ required: false,
41
+ }),
42
+ __metadata("design:type", String)
43
+ ], SendEmailResponseDto.prototype, "messageId", void 0);
44
+ __decorate([
45
+ ApiProperty({
46
+ description: 'Error message if failed',
47
+ example: 'Invalid recipient address',
48
+ required: false,
49
+ }),
50
+ __metadata("design:type", String)
51
+ ], SendEmailResponseDto.prototype, "error", void 0);
@@ -0,0 +1,35 @@
1
+ var EmailModule_1;
2
+ import { __decorate } from "tslib";
3
+ import { Module } from '@nestjs/common';
4
+ import { GmailProvider, } from './providers/gmail.provider.js';
5
+ import { EmailService } from './email.service.js';
6
+ import { EmailController } from './email.controller.js';
7
+ import { EMAIL_PROVIDER } from './email.types.js';
8
+ export { EMAIL_PROVIDER } from './email.types.js';
9
+ // Module
10
+ let EmailModule = EmailModule_1 = class EmailModule {
11
+ static forRoot(options) {
12
+ return {
13
+ module: EmailModule_1,
14
+ global: true,
15
+ controllers: [EmailController],
16
+ providers: [
17
+ {
18
+ provide: EMAIL_PROVIDER,
19
+ useFactory: () => {
20
+ switch (options.provider) {
21
+ case 'gmail':
22
+ return new GmailProvider(options.config);
23
+ }
24
+ },
25
+ },
26
+ EmailService,
27
+ ],
28
+ exports: [EmailService],
29
+ };
30
+ }
31
+ };
32
+ EmailModule = EmailModule_1 = __decorate([
33
+ Module({})
34
+ ], EmailModule);
35
+ export { EmailModule };
@@ -0,0 +1,8 @@
1
+ import type { EmailProvider } from './email.types.js';
2
+ import { SendEmailDto, SendEmailResponseDto } from './email.dto.js';
3
+ export declare class EmailService {
4
+ private readonly emailProvider;
5
+ constructor(emailProvider: EmailProvider);
6
+ send(dto: SendEmailDto): Promise<SendEmailResponseDto>;
7
+ }
8
+ //# sourceMappingURL=email.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.service.d.ts","sourceRoot":"","sources":["../../src/lib/email.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,qBACa,YAAY;IAEG,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAGjE,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAY7D"}
@@ -0,0 +1,27 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { Injectable, Inject } from '@nestjs/common';
3
+ import { EMAIL_PROVIDER } from './email.types.js';
4
+ let EmailService = class EmailService {
5
+ constructor(emailProvider) {
6
+ this.emailProvider = emailProvider;
7
+ }
8
+ async send(dto) {
9
+ try {
10
+ const result = await this.emailProvider.send({
11
+ to: [dto.to],
12
+ subject: dto.subject,
13
+ text: dto.body,
14
+ });
15
+ return { success: true, messageId: result.messageId };
16
+ }
17
+ catch (error) {
18
+ return { success: false, error: error.message };
19
+ }
20
+ }
21
+ };
22
+ EmailService = __decorate([
23
+ Injectable(),
24
+ __param(0, Inject(EMAIL_PROVIDER)),
25
+ __metadata("design:paramtypes", [Object])
26
+ ], EmailService);
27
+ export { EmailService };
@@ -0,0 +1,15 @@
1
+ export interface EmailMessage {
2
+ to: string[];
3
+ from?: string;
4
+ subject: string;
5
+ text?: string;
6
+ html?: string;
7
+ }
8
+ export interface EmailResult {
9
+ messageId?: string;
10
+ }
11
+ export interface EmailProvider {
12
+ send(message: EmailMessage): Promise<EmailResult>;
13
+ }
14
+ export declare const EMAIL_PROVIDER: unique symbol;
15
+ //# sourceMappingURL=email.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.types.d.ts","sourceRoot":"","sources":["../../src/lib/email.types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACnD;AAGD,eAAO,MAAM,cAAc,eAA2B,CAAC"}
@@ -0,0 +1,2 @@
1
+ // DI token
2
+ export const EMAIL_PROVIDER = Symbol('EMAIL_PROVIDER');
@@ -0,0 +1,15 @@
1
+ import { EmailMessage, EmailResult, EmailProvider } from '../email.js';
2
+ export interface GmailProviderConfig {
3
+ clientEmail: string;
4
+ privateKey: string;
5
+ impersonateEmail: string;
6
+ }
7
+ export declare class GmailProvider implements EmailProvider {
8
+ private client;
9
+ private defaultFrom;
10
+ constructor(config: GmailProviderConfig);
11
+ send(message: EmailMessage): Promise<EmailResult>;
12
+ private buildRawMessage;
13
+ private toBase64Url;
14
+ }
15
+ //# sourceMappingURL=gmail.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.provider.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/gmail.provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,mBAAmB;IAYjC,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAWvD,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,WAAW;CAOpB"}
@@ -0,0 +1,43 @@
1
+ import { gmail, auth } from '@googleapis/gmail';
2
+ export class GmailProvider {
3
+ constructor(config) {
4
+ const jwt = new auth.JWT({
5
+ email: config.clientEmail,
6
+ key: config.privateKey.replace(/\\n/g, '\n'),
7
+ scopes: ['https://www.googleapis.com/auth/gmail.send'],
8
+ subject: config.impersonateEmail,
9
+ });
10
+ this.client = gmail({ version: 'v1', auth: jwt });
11
+ this.defaultFrom = config.impersonateEmail;
12
+ }
13
+ async send(message) {
14
+ const raw = this.buildRawMessage(message);
15
+ const res = await this.client.users.messages.send({
16
+ userId: 'me',
17
+ requestBody: { raw },
18
+ });
19
+ return { messageId: res.data.id || undefined };
20
+ }
21
+ buildRawMessage(message) {
22
+ const from = message.from || this.defaultFrom;
23
+ const to = message.to.join(', ');
24
+ const contentType = message.html ? 'text/html' : 'text/plain';
25
+ const body = message.html || message.text || '';
26
+ const headers = [
27
+ `From: ${from}`,
28
+ `To: ${to}`,
29
+ `Subject: ${message.subject}`,
30
+ 'MIME-Version: 1.0',
31
+ `Content-Type: ${contentType}; charset=UTF-8`,
32
+ ].join('\r\n');
33
+ const rawMessage = `${headers}\r\n\r\n${body}`;
34
+ return this.toBase64Url(rawMessage);
35
+ }
36
+ toBase64Url(str) {
37
+ return Buffer.from(str)
38
+ .toString('base64')
39
+ .replace(/\+/g, '-')
40
+ .replace(/\//g, '_')
41
+ .replace(/=+$/, '');
42
+ }
43
+ }
@@ -0,0 +1,3 @@
1
+ export { GmailProvider } from './gmail.provider.js';
2
+ export type { GmailProviderConfig } from './gmail.provider.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { GmailProvider } from './gmail.provider.js';