@webiny/api-mailer 6.4.0-beta.3 → 6.4.0-beta.5
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.
- package/domain/MailTransport/abstractions.d.ts +1 -7
- package/domain/MailTransport/abstractions.js +1 -2
- package/domain/MailTransport/abstractions.js.map +1 -1
- package/domain/MailerService/abstractions.d.ts +2 -2
- package/domain/MailerService/abstractions.js.map +1 -1
- package/domain/MailerService/errors.d.ts +4 -0
- package/domain/MailerService/errors.js +8 -1
- package/domain/MailerService/errors.js.map +1 -1
- package/features/DummyTransport/DummyMailTransportFactory.d.ts +1 -0
- package/features/DummyTransport/DummyMailTransportFactory.js +3 -0
- package/features/DummyTransport/DummyMailTransportFactory.js.map +1 -1
- package/features/GetSettings/GetSettingsRepository.js +4 -2
- package/features/GetSettings/GetSettingsRepository.js.map +1 -1
- package/features/MailerService/MailerService.d.ts +3 -4
- package/features/MailerService/MailerService.js +26 -16
- package/features/MailerService/MailerService.js.map +1 -1
- package/features/MailerService/feature.js +0 -2
- package/features/MailerService/feature.js.map +1 -1
- package/features/SaveSettings/SaveSettingsRepository.js +6 -4
- package/features/SaveSettings/SaveSettingsRepository.js.map +1 -1
- package/features/SaveSettings/SaveSettingsUseCase.d.ts +4 -4
- package/features/SaveSettings/SaveSettingsUseCase.js +11 -6
- package/features/SaveSettings/SaveSettingsUseCase.js.map +1 -1
- package/features/SaveSettings/abstractions.d.ts +1 -0
- package/features/SaveSettings/abstractions.js.map +1 -1
- package/features/SaveSettings/validation.d.ts +1 -0
- package/features/SaveSettings/validation.js +1 -0
- package/features/SaveSettings/validation.js.map +1 -1
- package/features/SendMail/SendMailUseCase.d.ts +1 -1
- package/features/SmtpTransport/SmtpConfig.js +1 -0
- package/features/SmtpTransport/SmtpConfig.js.map +1 -1
- package/features/SmtpTransport/SmtpMailTransportFactory.d.ts +1 -0
- package/features/SmtpTransport/SmtpMailTransportFactory.js +3 -0
- package/features/SmtpTransport/SmtpMailTransportFactory.js.map +1 -1
- package/graphql/settings.js +4 -8
- package/graphql/settings.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/package.json +20 -18
- package/types.d.ts +1 -0
- package/features/MailerService/ActiveTransport.d.ts +0 -10
- package/features/MailerService/ActiveTransport.js +0 -24
- package/features/MailerService/ActiveTransport.js.map +0 -1
|
@@ -10,6 +10,7 @@ export declare namespace MailTransport {
|
|
|
10
10
|
}
|
|
11
11
|
export interface IMailTransportFactory {
|
|
12
12
|
name: string;
|
|
13
|
+
canUse(settings: TransportSettings | null): boolean;
|
|
13
14
|
createTransport(settings: TransportSettings): Promise<IMailTransport>;
|
|
14
15
|
}
|
|
15
16
|
export declare const MailTransportFactory: import("@webiny/di").Abstraction<IMailTransportFactory>;
|
|
@@ -17,10 +18,3 @@ export declare namespace MailTransportFactory {
|
|
|
17
18
|
type Interface = IMailTransportFactory;
|
|
18
19
|
type Return = Promise<IMailTransport>;
|
|
19
20
|
}
|
|
20
|
-
export interface IActiveTransport {
|
|
21
|
-
name(): string | null;
|
|
22
|
-
}
|
|
23
|
-
export declare const ActiveTransport: import("@webiny/di").Abstraction<IActiveTransport>;
|
|
24
|
-
export declare namespace ActiveTransport {
|
|
25
|
-
type Interface = IActiveTransport;
|
|
26
|
-
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createAbstraction } from "@webiny/feature/api";
|
|
2
2
|
const MailTransport = createAbstraction("MailTransport");
|
|
3
3
|
const MailTransportFactory = createAbstraction("MailTransportFactory");
|
|
4
|
-
|
|
5
|
-
export { ActiveTransport, MailTransport, MailTransportFactory };
|
|
4
|
+
export { MailTransport, MailTransportFactory };
|
|
6
5
|
|
|
7
6
|
//# sourceMappingURL=abstractions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/MailTransport/abstractions.js","sources":["../../../src/domain/MailTransport/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse, TransportSettings } from \"~/types.js\";\n\nexport interface IMailTransport {\n name: string;\n send(params: TransportSendData): Promise<TransportSendResponse>;\n}\n\nexport const MailTransport = createAbstraction<IMailTransport>(\"MailTransport\");\n\nexport namespace MailTransport {\n export type Interface = IMailTransport;\n export type SendParams = TransportSendData;\n}\n\nexport interface IMailTransportFactory {\n name: string;\n createTransport(settings: TransportSettings): Promise<IMailTransport>;\n}\n\nexport const MailTransportFactory =\n createAbstraction<IMailTransportFactory>(\"MailTransportFactory\");\n\nexport namespace MailTransportFactory {\n export type Interface = IMailTransportFactory;\n export type Return = Promise<IMailTransport>;\n}\n
|
|
1
|
+
{"version":3,"file":"domain/MailTransport/abstractions.js","sources":["../../../src/domain/MailTransport/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse, TransportSettings } from \"~/types.js\";\n\nexport interface IMailTransport {\n name: string;\n send(params: TransportSendData): Promise<TransportSendResponse>;\n}\n\nexport const MailTransport = createAbstraction<IMailTransport>(\"MailTransport\");\n\nexport namespace MailTransport {\n export type Interface = IMailTransport;\n export type SendParams = TransportSendData;\n}\n\nexport interface IMailTransportFactory {\n name: string;\n canUse(settings: TransportSettings | null): boolean;\n createTransport(settings: TransportSettings): Promise<IMailTransport>;\n}\n\nexport const MailTransportFactory =\n createAbstraction<IMailTransportFactory>(\"MailTransportFactory\");\n\nexport namespace MailTransportFactory {\n export type Interface = IMailTransportFactory;\n export type Return = Promise<IMailTransport>;\n}\n"],"names":["MailTransport","createAbstraction","MailTransportFactory"],"mappings":";AAQO,MAAMA,gBAAgBC,kBAAkC;AAaxD,MAAMC,uBACTD,kBAAyC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Result } from "@webiny/feature/api";
|
|
2
2
|
import type { TransportSendData, TransportSendResponse } from "../../types.js";
|
|
3
|
-
import { NoTransportAvailableError,
|
|
3
|
+
import { NoTransportAvailableError, TransportCreateError, TransportSendError } from "./errors.js";
|
|
4
4
|
export interface IMailerServiceErrors {
|
|
5
5
|
noTransport: NoTransportAvailableError;
|
|
6
|
-
|
|
6
|
+
transportCreate: TransportCreateError;
|
|
7
7
|
transportSend: TransportSendError;
|
|
8
8
|
}
|
|
9
9
|
type MailerServiceError = IMailerServiceErrors[keyof IMailerServiceErrors];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/MailerService/abstractions.js","sources":["../../../src/domain/MailerService/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse } from \"~/types.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"domain/MailerService/abstractions.js","sources":["../../../src/domain/MailerService/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse } from \"~/types.js\";\nimport { NoTransportAvailableError, TransportCreateError, TransportSendError } from \"./errors.js\";\n\nexport interface IMailerServiceErrors {\n noTransport: NoTransportAvailableError;\n transportCreate: TransportCreateError;\n transportSend: TransportSendError;\n}\n\ntype MailerServiceError = IMailerServiceErrors[keyof IMailerServiceErrors];\n\nexport interface IMailerService {\n sendMail<T = any>(\n data: TransportSendData\n ): Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n}\n\nexport const MailerService = createAbstraction<IMailerService>(\"MailerService\");\n\nexport namespace MailerService {\n export type Interface = IMailerService;\n export type Return<T = any> = Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n export type Error = MailerServiceError;\n}\n"],"names":["MailerService","createAbstraction"],"mappings":";AAmBO,MAAMA,gBAAgBC,kBAAkC"}
|
|
@@ -8,6 +8,10 @@ export declare class NoSettingsConfiguredError extends BaseError {
|
|
|
8
8
|
readonly code: "Mailer/MailerService/NoSettingsConfigured";
|
|
9
9
|
constructor();
|
|
10
10
|
}
|
|
11
|
+
export declare class TransportCreateError extends BaseError {
|
|
12
|
+
readonly code: "Mailer/MailerService/TransportCreateError";
|
|
13
|
+
constructor(error: unknown);
|
|
14
|
+
}
|
|
11
15
|
export declare class TransportSendError extends BaseError<{
|
|
12
16
|
error: TransportSendResponse["error"];
|
|
13
17
|
}> {
|
|
@@ -13,6 +13,13 @@ class NoSettingsConfiguredError extends BaseError {
|
|
|
13
13
|
}), this.code = "Mailer/MailerService/NoSettingsConfigured";
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
class TransportCreateError extends BaseError {
|
|
17
|
+
constructor(error){
|
|
18
|
+
super({
|
|
19
|
+
message: error instanceof Error ? error.message : String(error)
|
|
20
|
+
}), this.code = "Mailer/MailerService/TransportCreateError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
class TransportSendError extends BaseError {
|
|
17
24
|
constructor(error){
|
|
18
25
|
super({
|
|
@@ -23,6 +30,6 @@ class TransportSendError extends BaseError {
|
|
|
23
30
|
}), this.code = "Mailer/MailerService/TransportSendError";
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
|
-
export { NoSettingsConfiguredError, NoTransportAvailableError, TransportSendError };
|
|
33
|
+
export { NoSettingsConfiguredError, NoTransportAvailableError, TransportCreateError, TransportSendError };
|
|
27
34
|
|
|
28
35
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/MailerService/errors.js","sources":["../../../src/domain/MailerService/errors.ts"],"sourcesContent":["import { BaseError } from \"@webiny/feature/api\";\nimport type { TransportSendResponse } from \"~/types.js\";\n\nexport class NoTransportAvailableError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoTransportAvailable\" as const;\n\n constructor() {\n super({\n message: \"There is no transport available.\"\n });\n }\n}\n\nexport class NoSettingsConfiguredError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoSettingsConfigured\" as const;\n\n constructor() {\n super({\n message: \"No mailer settings are configured and no environment variables are set.\"\n });\n }\n}\n\nexport class TransportSendError extends BaseError<{ error: TransportSendResponse[\"error\"] }> {\n override readonly code = \"Mailer/MailerService/TransportSendError\" as const;\n\n constructor(error: NonNullable<TransportSendResponse[\"error\"]>) {\n super({\n message: error.message,\n data: {\n error\n }\n });\n }\n}\n"],"names":["NoTransportAvailableError","BaseError","NoSettingsConfiguredError","
|
|
1
|
+
{"version":3,"file":"domain/MailerService/errors.js","sources":["../../../src/domain/MailerService/errors.ts"],"sourcesContent":["import { BaseError } from \"@webiny/feature/api\";\nimport type { TransportSendResponse } from \"~/types.js\";\n\nexport class NoTransportAvailableError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoTransportAvailable\" as const;\n\n constructor() {\n super({\n message: \"There is no transport available.\"\n });\n }\n}\n\nexport class NoSettingsConfiguredError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoSettingsConfigured\" as const;\n\n constructor() {\n super({\n message: \"No mailer settings are configured and no environment variables are set.\"\n });\n }\n}\n\nexport class TransportCreateError extends BaseError {\n override readonly code = \"Mailer/MailerService/TransportCreateError\" as const;\n\n constructor(error: unknown) {\n super({\n message: error instanceof Error ? error.message : String(error)\n });\n }\n}\n\nexport class TransportSendError extends BaseError<{ error: TransportSendResponse[\"error\"] }> {\n override readonly code = \"Mailer/MailerService/TransportSendError\" as const;\n\n constructor(error: NonNullable<TransportSendResponse[\"error\"]>) {\n super({\n message: error.message,\n data: {\n error\n }\n });\n }\n}\n"],"names":["NoTransportAvailableError","BaseError","NoSettingsConfiguredError","TransportCreateError","error","Error","String","TransportSendError"],"mappings":";AAGO,MAAMA,kCAAkCC;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAMC,kCAAkCD;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAME,6BAA6BF;IAGtC,YAAYG,KAAc,CAAE;QACxB,KAAK,CAAC;YACF,SAASA,iBAAiBC,QAAQD,MAAM,OAAO,GAAGE,OAAOF;QAC7D,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAMG,2BAA2BN;IAGpC,YAAYG,KAAkD,CAAE;QAC5D,KAAK,CAAC;YACF,SAASA,MAAM,OAAO;YACtB,MAAM;gBACFA;YACJ;QACJ,SARc,IAAI,GAAG;IASzB;AACJ"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type IMailTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
2
2
|
declare class DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {
|
|
3
3
|
readonly name = "Mailer/DummyTransport";
|
|
4
|
+
canUse(): boolean;
|
|
4
5
|
createTransport(): Promise<IMailTransport>;
|
|
5
6
|
}
|
|
6
7
|
export declare const DummyMailTransportFactory: typeof DummyMailTransportFactoryImpl & {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
2
2
|
import { DummyMailTransport } from "./DummyMailTransport.js";
|
|
3
3
|
class DummyMailTransportFactoryImpl {
|
|
4
|
+
canUse() {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
4
7
|
async createTransport() {
|
|
5
8
|
return new DummyMailTransport();
|
|
6
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/DummyTransport/DummyMailTransportFactory.js","sources":["../../../src/features/DummyTransport/DummyMailTransportFactory.ts"],"sourcesContent":["import { type IMailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { DummyMailTransport } from \"./DummyMailTransport.js\";\n\nclass DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/DummyTransport\";\n\n async createTransport(): Promise<IMailTransport> {\n return new DummyMailTransport();\n }\n}\n\nexport const DummyMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: DummyMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["DummyMailTransportFactoryImpl","DummyMailTransport","DummyMailTransportFactory","MailTransportFactory"],"mappings":";;AAGA,MAAMA;IAGF,MAAM,kBAA2C;QAC7C,OAAO,IAAIC;IACf;;
|
|
1
|
+
{"version":3,"file":"features/DummyTransport/DummyMailTransportFactory.js","sources":["../../../src/features/DummyTransport/DummyMailTransportFactory.ts"],"sourcesContent":["import { type IMailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { DummyMailTransport } from \"./DummyMailTransport.js\";\n\nclass DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/DummyTransport\";\n\n canUse(): boolean {\n return true;\n }\n\n async createTransport(): Promise<IMailTransport> {\n return new DummyMailTransport();\n }\n}\n\nexport const DummyMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: DummyMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["DummyMailTransportFactoryImpl","DummyMailTransport","DummyMailTransportFactory","MailTransportFactory"],"mappings":";;AAGA,MAAMA;IAGF,SAAkB;QACd,OAAO;IACX;IAEA,MAAM,kBAA2C;QAC7C,OAAO,IAAIC;IACf;;aARgB,IAAI,GAAG;;AAS3B;AAEO,MAAMC,4BAA4BC,qBAAqB,oBAAoB,CAAC;IAC/E,gBAAgBH;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -26,10 +26,12 @@ class GetSettingsRepositoryImpl {
|
|
|
26
26
|
settings: null,
|
|
27
27
|
source: null
|
|
28
28
|
});
|
|
29
|
-
const password = settings.password ? this.encryption.decrypt(String(settings.password)) : "";
|
|
29
|
+
const password = settings.password ? await this.encryption.decrypt(String(settings.password)) : "";
|
|
30
|
+
const port = Number(settings.port || 587);
|
|
30
31
|
const transportSettings = {
|
|
31
32
|
host: String(settings.host || ""),
|
|
32
|
-
port
|
|
33
|
+
port,
|
|
34
|
+
secure: settings.secure ?? 465 === port,
|
|
33
35
|
user: String(settings.user || ""),
|
|
34
36
|
password,
|
|
35
37
|
from: String(settings.from || ""),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/GetSettings/GetSettingsRepository.js","sources":["../../../src/features/GetSettings/GetSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { GetSettingsRepository, type ISettingsWithSource } from \"./abstractions.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nclass GetSettingsRepositoryImpl implements GetSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface,\n private codeSettings: CodeMailerSettings.Interface\n ) {}\n\n async get(transportName: string): Promise<Result<ISettingsWithSource>> {\n // Code-defined settings win over the KV store.\n const codeSettingsValue = this.codeSettings.get(transportName);\n if (codeSettingsValue !== null) {\n return Result.ok({\n settings: codeSettingsValue,\n source: \"code\"\n });\n }\n\n const result = await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n\n if (result.isFail()) {\n return Result.ok({ settings: null, source: null });\n }\n\n const settings = result.value;\n if (!settings) {\n return Result.ok({ settings: null, source: null });\n }\n\n // Decrypt password if present.\n const password = settings.password\n ? this.encryption.decrypt(String(settings.password))\n : \"\";\n\n const transportSettings: TransportSettings = {\n host: String(settings.host || \"\"),\n port:
|
|
1
|
+
{"version":3,"file":"features/GetSettings/GetSettingsRepository.js","sources":["../../../src/features/GetSettings/GetSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { GetSettingsRepository, type ISettingsWithSource } from \"./abstractions.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nclass GetSettingsRepositoryImpl implements GetSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface,\n private codeSettings: CodeMailerSettings.Interface\n ) {}\n\n async get(transportName: string): Promise<Result<ISettingsWithSource>> {\n // Code-defined settings win over the KV store.\n const codeSettingsValue = this.codeSettings.get(transportName);\n if (codeSettingsValue !== null) {\n return Result.ok({\n settings: codeSettingsValue,\n source: \"code\"\n });\n }\n\n const result = await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n\n if (result.isFail()) {\n return Result.ok({ settings: null, source: null });\n }\n\n const settings = result.value;\n if (!settings) {\n return Result.ok({ settings: null, source: null });\n }\n\n // Decrypt password if present.\n const password = settings.password\n ? await this.encryption.decrypt(String(settings.password))\n : \"\";\n\n const port = Number(settings.port || 587);\n\n const transportSettings: TransportSettings = {\n host: String(settings.host || \"\"),\n port,\n secure: settings.secure ?? port === 465,\n user: String(settings.user || \"\"),\n password,\n from: String(settings.from || \"\"),\n replyTo: settings.replyTo ? String(settings.replyTo) : undefined\n };\n\n return Result.ok({ settings: transportSettings, source: \"storage\" });\n }\n}\n\nexport const GetSettingsRepositoryImplementation = GetSettingsRepository.createImplementation({\n implementation: GetSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption, CodeMailerSettings]\n});\n"],"names":["GetSettingsRepositoryImpl","keyValueStore","encryption","codeSettings","transportName","codeSettingsValue","Result","result","MAILER_TRANSPORT_SETTINGS","settings","password","String","port","Number","transportSettings","undefined","GetSettingsRepositoryImplementation","GetSettingsRepository","KeyValueStore","Encryption","CodeMailerSettings"],"mappings":";;;;;;AAQA,MAAMA;IACF,YACYC,aAAsC,EACtCC,UAAgC,EAChCC,YAA0C,CACpD;aAHUF,aAAa,GAAbA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;IACT;IAEH,MAAM,IAAIC,aAAqB,EAAwC;QAEnE,MAAMC,oBAAoB,IAAI,CAAC,YAAY,CAAC,GAAG,CAACD;QAChD,IAAIC,AAAsB,SAAtBA,mBACA,OAAOC,OAAO,EAAE,CAAC;YACb,UAAUD;YACV,QAAQ;QACZ;QAGJ,MAAME,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QAE/D,IAAID,OAAO,MAAM,IACb,OAAOD,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAGpD,MAAMG,WAAWF,OAAO,KAAK;QAC7B,IAAI,CAACE,UACD,OAAOH,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAIpD,MAAMI,WAAWD,SAAS,QAAQ,GAC5B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACE,OAAOF,SAAS,QAAQ,KACtD;QAEN,MAAMG,OAAOC,OAAOJ,SAAS,IAAI,IAAI;QAErC,MAAMK,oBAAuC;YACzC,MAAMH,OAAOF,SAAS,IAAI,IAAI;YAC9BG;YACA,QAAQH,SAAS,MAAM,IAAIG,AAAS,QAATA;YAC3B,MAAMD,OAAOF,SAAS,IAAI,IAAI;YAC9BC;YACA,MAAMC,OAAOF,SAAS,IAAI,IAAI;YAC9B,SAASA,SAAS,OAAO,GAAGE,OAAOF,SAAS,OAAO,IAAIM;QAC3D;QAEA,OAAOT,OAAO,EAAE,CAAC;YAAE,UAAUQ;YAAmB,QAAQ;QAAU;IACtE;AACJ;AAEO,MAAME,sCAAsCC,sBAAsB,oBAAoB,CAAC;IAC1F,gBAAgBjB;IAChB,cAAc;QAACkB;QAAeC;QAAYC;KAAmB;AACjE"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { MailerService as Abstraction } from "../../domain/MailerService/abstractions.js";
|
|
2
|
-
import {
|
|
2
|
+
import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
3
3
|
import { GetSettingsRepository } from "../GetSettings/abstractions.js";
|
|
4
4
|
import type { TransportSendData } from "../../types.js";
|
|
5
5
|
declare class MailerServiceImpl implements Abstraction.Interface {
|
|
6
6
|
private getSettingsRepository;
|
|
7
|
-
private activeTransport;
|
|
8
7
|
private transportFactories;
|
|
9
|
-
constructor(getSettingsRepository: GetSettingsRepository.Interface,
|
|
8
|
+
constructor(getSettingsRepository: GetSettingsRepository.Interface, transportFactories: MailTransportFactory.Interface[]);
|
|
10
9
|
sendMail<T = any>(data: TransportSendData): Abstraction.Return<T>;
|
|
11
|
-
private
|
|
10
|
+
private resolveTransport;
|
|
12
11
|
}
|
|
13
12
|
export declare const MailerService: typeof MailerServiceImpl & {
|
|
14
13
|
__abstraction: import("@webiny/di").Abstraction<import("~/domain/MailerService/abstractions.js").IMailerService>;
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import { Result } from "@webiny/feature/api";
|
|
2
2
|
import { MailerService } from "../../domain/MailerService/abstractions.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { NoTransportAvailableError, TransportCreateError, TransportSendError } from "../../domain/MailerService/errors.js";
|
|
4
|
+
import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
5
5
|
import { GetSettingsRepository } from "../GetSettings/abstractions.js";
|
|
6
6
|
class MailerServiceImpl {
|
|
7
|
-
constructor(getSettingsRepository,
|
|
7
|
+
constructor(getSettingsRepository, transportFactories){
|
|
8
8
|
this.getSettingsRepository = getSettingsRepository;
|
|
9
|
-
this.activeTransport = activeTransport;
|
|
10
9
|
this.transportFactories = transportFactories;
|
|
11
10
|
}
|
|
12
11
|
async sendMail(data) {
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
15
|
-
const result = await this.getSettingsRepository.get(transportName);
|
|
16
|
-
const { settings } = result.value;
|
|
17
|
-
if (!settings) return Result.fail(new NoSettingsConfiguredError());
|
|
18
|
-
const transport = await this.getTransport(transportName, settings);
|
|
19
|
-
if (!transport) return Result.fail(new NoTransportAvailableError());
|
|
12
|
+
const { factory, transport } = await this.resolveTransport();
|
|
13
|
+
if (!factory || !transport) return Result.fail(new NoTransportAvailableError());
|
|
20
14
|
try {
|
|
21
15
|
const response = await transport.send(data);
|
|
22
16
|
if (response.error) return Result.fail(new TransportSendError(response.error));
|
|
@@ -25,17 +19,33 @@ class MailerServiceImpl {
|
|
|
25
19
|
return Result.fail(new TransportSendError(error));
|
|
26
20
|
}
|
|
27
21
|
}
|
|
28
|
-
async
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
async resolveTransport() {
|
|
23
|
+
const factories = [
|
|
24
|
+
...this.transportFactories
|
|
25
|
+
].reverse();
|
|
26
|
+
for (const factory of factories){
|
|
27
|
+
const result = await this.getSettingsRepository.get(factory.name);
|
|
28
|
+
const { settings } = result.value;
|
|
29
|
+
if (factory.canUse(settings)) try {
|
|
30
|
+
const transport = await factory.createTransport(settings);
|
|
31
|
+
return {
|
|
32
|
+
factory,
|
|
33
|
+
transport
|
|
34
|
+
};
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw new TransportCreateError(error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
factory: null,
|
|
41
|
+
transport: null
|
|
42
|
+
};
|
|
32
43
|
}
|
|
33
44
|
}
|
|
34
45
|
const MailerService_MailerService = MailerService.createImplementation({
|
|
35
46
|
implementation: MailerServiceImpl,
|
|
36
47
|
dependencies: [
|
|
37
48
|
GetSettingsRepository,
|
|
38
|
-
ActiveTransport,
|
|
39
49
|
[
|
|
40
50
|
MailTransportFactory,
|
|
41
51
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/MailerService/MailerService.js","sources":["../../../src/features/MailerService/MailerService.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { MailerService as Abstraction } from \"~/domain/MailerService/abstractions.js\";\nimport {\n NoTransportAvailableError,\n
|
|
1
|
+
{"version":3,"file":"features/MailerService/MailerService.js","sources":["../../../src/features/MailerService/MailerService.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { MailerService as Abstraction } from \"~/domain/MailerService/abstractions.js\";\nimport {\n NoTransportAvailableError,\n TransportCreateError,\n TransportSendError\n} from \"~/domain/MailerService/errors.js\";\nimport { MailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { GetSettingsRepository } from \"../GetSettings/abstractions.js\";\nimport type { TransportSendData } from \"~/types.js\";\n\nclass MailerServiceImpl implements Abstraction.Interface {\n constructor(\n private getSettingsRepository: GetSettingsRepository.Interface,\n private transportFactories: MailTransportFactory.Interface[]\n ) {}\n\n async sendMail<T = any>(data: TransportSendData): Abstraction.Return<T> {\n const { factory, transport } = await this.resolveTransport();\n\n if (!factory || !transport) {\n return Result.fail(new NoTransportAvailableError());\n }\n\n try {\n const response = await transport.send(data);\n\n if (response.error) {\n return Result.fail(new TransportSendError(response.error));\n }\n\n return Result.ok(response);\n } catch (error) {\n return Result.fail(new TransportSendError(error));\n }\n }\n\n private async resolveTransport(): Promise<{\n factory: MailTransportFactory.Interface | null;\n transport: MailTransport.Interface | null;\n }> {\n const factories = [...this.transportFactories].reverse();\n\n for (const factory of factories) {\n const result = await this.getSettingsRepository.get(factory.name);\n const { settings } = result.value;\n\n if (!factory.canUse(settings)) {\n continue;\n }\n\n try {\n const transport = await factory.createTransport(settings!);\n return { factory, transport };\n } catch (error) {\n throw new TransportCreateError(error);\n }\n }\n\n return { factory: null, transport: null };\n }\n}\n\nexport const MailerService = Abstraction.createImplementation({\n implementation: MailerServiceImpl,\n dependencies: [GetSettingsRepository, [MailTransportFactory, { multiple: true }]]\n});\n"],"names":["MailerServiceImpl","getSettingsRepository","transportFactories","data","factory","transport","Result","NoTransportAvailableError","response","TransportSendError","error","factories","result","settings","TransportCreateError","MailerService","Abstraction","GetSettingsRepository","MailTransportFactory"],"mappings":";;;;;AAWA,MAAMA;IACF,YACYC,qBAAsD,EACtDC,kBAAoD,CAC9D;aAFUD,qBAAqB,GAArBA;aACAC,kBAAkB,GAAlBA;IACT;IAEH,MAAM,SAAkBC,IAAuB,EAAyB;QACpE,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB;QAE1D,IAAI,CAACD,WAAW,CAACC,WACb,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,IAAI;YACA,MAAMC,WAAW,MAAMH,UAAU,IAAI,CAACF;YAEtC,IAAIK,SAAS,KAAK,EACd,OAAOF,OAAO,IAAI,CAAC,IAAIG,mBAAmBD,SAAS,KAAK;YAG5D,OAAOF,OAAO,EAAE,CAACE;QACrB,EAAE,OAAOE,OAAO;YACZ,OAAOJ,OAAO,IAAI,CAAC,IAAIG,mBAAmBC;QAC9C;IACJ;IAEA,MAAc,mBAGX;QACC,MAAMC,YAAY;eAAI,IAAI,CAAC,kBAAkB;SAAC,CAAC,OAAO;QAEtD,KAAK,MAAMP,WAAWO,UAAW;YAC7B,MAAMC,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAACR,QAAQ,IAAI;YAChE,MAAM,EAAES,QAAQ,EAAE,GAAGD,OAAO,KAAK;YAEjC,IAAKR,QAAQ,MAAM,CAACS,WAIpB,IAAI;gBACA,MAAMR,YAAY,MAAMD,QAAQ,eAAe,CAACS;gBAChD,OAAO;oBAAET;oBAASC;gBAAU;YAChC,EAAE,OAAOK,OAAO;gBACZ,MAAM,IAAII,qBAAqBJ;YACnC;QACJ;QAEA,OAAO;YAAE,SAAS;YAAM,WAAW;QAAK;IAC5C;AACJ;AAEO,MAAMK,8BAAgBC,cAAAA,oBAAgC,CAAC;IAC1D,gBAAgBhB;IAChB,cAAc;QAACiB;QAAuB;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAAC;AACrF"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { createFeature } from "@webiny/feature/api";
|
|
2
2
|
import { MailerService } from "./MailerService.js";
|
|
3
|
-
import { ActiveTransport } from "./ActiveTransport.js";
|
|
4
3
|
const MailerServiceFeature = createFeature({
|
|
5
4
|
name: "Mailer/MailerService",
|
|
6
5
|
register (container) {
|
|
7
|
-
container.register(ActiveTransport).inSingletonScope();
|
|
8
6
|
container.register(MailerService).inSingletonScope();
|
|
9
7
|
}
|
|
10
8
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/MailerService/feature.js","sources":["../../../src/features/MailerService/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { MailerService } from \"./MailerService.js\";\
|
|
1
|
+
{"version":3,"file":"features/MailerService/feature.js","sources":["../../../src/features/MailerService/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { MailerService } from \"./MailerService.js\";\n\nexport const MailerServiceFeature = createFeature({\n name: \"Mailer/MailerService\",\n register(container) {\n container.register(MailerService).inSingletonScope();\n }\n});\n"],"names":["MailerServiceFeature","createFeature","container","MailerService"],"mappings":";;AAGO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,eAAe,gBAAgB;IACtD;AACJ"}
|
|
@@ -4,7 +4,7 @@ import { SaveSettingsRepository } from "./abstractions.js";
|
|
|
4
4
|
import { SettingsPersistenceError } from "../../domain/errors.js";
|
|
5
5
|
import { KeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
|
|
6
6
|
import { MAILER_TRANSPORT_SETTINGS } from "../../constants.js";
|
|
7
|
-
const DEFAULT_PORT =
|
|
7
|
+
const DEFAULT_PORT = 587;
|
|
8
8
|
class SaveSettingsRepositoryImpl {
|
|
9
9
|
constructor(keyValueStore, encryption){
|
|
10
10
|
this.keyValueStore = keyValueStore;
|
|
@@ -15,11 +15,13 @@ class SaveSettingsRepositoryImpl {
|
|
|
15
15
|
const existingSettings = existingResult.isOk() ? existingResult.value : null;
|
|
16
16
|
const transportSettings = existingSettings ?? {};
|
|
17
17
|
let passwordToStore = input.password || "";
|
|
18
|
-
if (!input.password && existingSettings) passwordToStore = this.encryption.decrypt(transportSettings.password || "");
|
|
19
|
-
const encryptedPassword = this.encryption.encrypt(passwordToStore);
|
|
18
|
+
if (!input.password && existingSettings) passwordToStore = await this.encryption.decrypt(transportSettings.password || "");
|
|
19
|
+
const encryptedPassword = await this.encryption.encrypt(passwordToStore);
|
|
20
|
+
const port = input.port ?? transportSettings.port ?? DEFAULT_PORT;
|
|
20
21
|
const data = {
|
|
21
22
|
host: input.host ?? transportSettings.host,
|
|
22
|
-
port
|
|
23
|
+
port,
|
|
24
|
+
secure: input.secure ?? transportSettings.secure ?? 465 === port,
|
|
23
25
|
user: input.user ?? transportSettings.user,
|
|
24
26
|
password: encryptedPassword,
|
|
25
27
|
from: input.from ?? transportSettings.from,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SaveSettings/SaveSettingsRepository.js","sources":["../../../src/features/SaveSettings/SaveSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { SaveSettingsRepository, type SaveSettingsInput } from \"./abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SettingsPersistenceError } from \"~/domain/errors.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nconst DEFAULT_PORT =
|
|
1
|
+
{"version":3,"file":"features/SaveSettings/SaveSettingsRepository.js","sources":["../../../src/features/SaveSettings/SaveSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { SaveSettingsRepository, type SaveSettingsInput } from \"./abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SettingsPersistenceError } from \"~/domain/errors.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nconst DEFAULT_PORT = 587;\n\nclass SaveSettingsRepositoryImpl implements SaveSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsRepository.Return {\n // Check if settings exist\n const existingResult =\n await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n const existingSettings = existingResult.isOk() ? existingResult.value : null;\n const transportSettings: Partial<TransportSettings> = existingSettings ?? {};\n\n // If updating and no password provided, keep the existing password\n let passwordToStore = input.password || \"\";\n if (!input.password && existingSettings) {\n passwordToStore = await this.encryption.decrypt(transportSettings.password || \"\");\n }\n\n // Encrypt password\n const encryptedPassword = await this.encryption.encrypt(passwordToStore);\n\n // Prepare data\n const port = input.port ?? transportSettings.port ?? DEFAULT_PORT;\n\n const data = {\n host: input.host ?? transportSettings.host,\n port,\n secure: input.secure ?? transportSettings.secure ?? port === 465,\n user: input.user ?? transportSettings.user,\n password: encryptedPassword,\n from: input.from ?? transportSettings.from,\n replyTo: input.replyTo ?? transportSettings.replyTo\n };\n\n // Save settings.\n const result = await this.keyValueStore.set(MAILER_TRANSPORT_SETTINGS, data);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n // Return the stored state without the password. Callers that need the\n // plaintext password go through GetSettingsRepository.get(transportName).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...savedSettings } = data as TransportSettings;\n return Result.ok(savedSettings);\n }\n}\n\nexport const SaveSettingsRepositoryImplementation = SaveSettingsRepository.createImplementation({\n implementation: SaveSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption]\n});\n"],"names":["DEFAULT_PORT","SaveSettingsRepositoryImpl","keyValueStore","encryption","input","existingResult","MAILER_TRANSPORT_SETTINGS","existingSettings","transportSettings","passwordToStore","encryptedPassword","port","data","result","Result","SettingsPersistenceError","_password","savedSettings","SaveSettingsRepositoryImplementation","SaveSettingsRepository","KeyValueStore","Encryption"],"mappings":";;;;;;AAQA,MAAMA,eAAe;AAErB,MAAMC;IACF,YACYC,aAAsC,EACtCC,UAAgC,CAC1C;aAFUD,aAAa,GAAbA;aACAC,UAAU,GAAVA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAAiC;QAEnE,MAAMC,iBACF,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QACpD,MAAMC,mBAAmBF,eAAe,IAAI,KAAKA,eAAe,KAAK,GAAG;QACxE,MAAMG,oBAAgDD,oBAAoB,CAAC;QAG3E,IAAIE,kBAAkBL,MAAM,QAAQ,IAAI;QACxC,IAAI,CAACA,MAAM,QAAQ,IAAIG,kBACnBE,kBAAkB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD,kBAAkB,QAAQ,IAAI;QAIlF,MAAME,oBAAoB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD;QAGxD,MAAME,OAAOP,MAAM,IAAI,IAAII,kBAAkB,IAAI,IAAIR;QAErD,MAAMY,OAAO;YACT,MAAMR,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1CG;YACA,QAAQP,MAAM,MAAM,IAAII,kBAAkB,MAAM,IAAIG,AAAS,QAATA;YACpD,MAAMP,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,UAAUE;YACV,MAAMN,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,SAASJ,MAAM,OAAO,IAAII,kBAAkB,OAAO;QACvD;QAGA,MAAMK,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAACP,2BAA2BM;QAEvE,IAAIC,OAAO,MAAM,IACb,OAAOC,OAAO,IAAI,CAAC,IAAIC,yBAAyBF,OAAO,KAAK;QAMhE,MAAM,EAAE,UAAUG,SAAS,EAAE,GAAGC,eAAe,GAAGL;QAClD,OAAOE,OAAO,EAAE,CAACG;IACrB;AACJ;AAEO,MAAMC,uCAAuCC,uBAAuB,oBAAoB,CAAC;IAC5F,gBAAgBlB;IAChB,cAAc;QAACmB;QAAeC;KAAW;AAC7C"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { EventPublisher
|
|
1
|
+
import { EventPublisher } from "@webiny/api-core/features/eventPublisher/index.js";
|
|
2
2
|
import { SaveSettingsUseCase, SaveSettingsRepository, type SaveSettingsInput } from "./abstractions.js";
|
|
3
3
|
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
4
4
|
import { CodeMailerSettings } from "../../domain/CodeMailerSettings/abstractions.js";
|
|
5
|
-
import {
|
|
5
|
+
import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
6
6
|
declare class SaveSettingsUseCaseImpl implements SaveSettingsUseCase.Interface {
|
|
7
7
|
private identityContext;
|
|
8
8
|
private eventPublisher;
|
|
9
9
|
private repository;
|
|
10
10
|
private codeSettings;
|
|
11
|
-
private
|
|
12
|
-
constructor(identityContext: IdentityContext.Interface, eventPublisher:
|
|
11
|
+
private transportFactories;
|
|
12
|
+
constructor(identityContext: IdentityContext.Interface, eventPublisher: EventPublisher.Interface, repository: SaveSettingsRepository.Interface, codeSettings: CodeMailerSettings.Interface, transportFactories: MailTransportFactory.Interface[]);
|
|
13
13
|
execute(input: SaveSettingsInput): SaveSettingsUseCase.Return;
|
|
14
14
|
}
|
|
15
15
|
export declare const SaveSettingsUseCaseImplementation: typeof SaveSettingsUseCaseImpl & {
|
|
@@ -6,22 +6,22 @@ import { saveValidation } from "./validation.js";
|
|
|
6
6
|
import { SettingsLockedByCode, SettingsNotAuthorized, SettingsPersistenceError, SettingsValidationError } from "../../domain/errors.js";
|
|
7
7
|
import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
|
|
8
8
|
import { CodeMailerSettings } from "../../domain/CodeMailerSettings/abstractions.js";
|
|
9
|
-
import {
|
|
9
|
+
import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
10
10
|
class SaveSettingsUseCaseImpl {
|
|
11
|
-
constructor(identityContext, eventPublisher, repository, codeSettings,
|
|
11
|
+
constructor(identityContext, eventPublisher, repository, codeSettings, transportFactories){
|
|
12
12
|
this.identityContext = identityContext;
|
|
13
13
|
this.eventPublisher = eventPublisher;
|
|
14
14
|
this.repository = repository;
|
|
15
15
|
this.codeSettings = codeSettings;
|
|
16
|
-
this.
|
|
16
|
+
this.transportFactories = transportFactories;
|
|
17
17
|
}
|
|
18
18
|
async execute(input) {
|
|
19
19
|
const permission = await this.identityContext.getPermission("mailer.settings");
|
|
20
20
|
if (!permission) return Result.fail(new SettingsNotAuthorized());
|
|
21
21
|
const validationResult = saveValidation.safeParse(input);
|
|
22
22
|
if (!validationResult.success) return Result.fail(new SettingsValidationError(validationResult.error.issues));
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
23
|
+
const isLockedByCode = this.transportFactories.some((f)=>null !== this.codeSettings.get(f.name));
|
|
24
|
+
if (isLockedByCode) return Result.fail(new SettingsLockedByCode());
|
|
25
25
|
const { password: _beforePassword, ...inputForEvent } = input;
|
|
26
26
|
const beforeSaveEvent = new MailerSettingsBeforeSaveEvent({
|
|
27
27
|
input: inputForEvent
|
|
@@ -43,7 +43,12 @@ const SaveSettingsUseCaseImplementation = SaveSettingsUseCase.createImplementati
|
|
|
43
43
|
EventPublisher,
|
|
44
44
|
SaveSettingsRepository,
|
|
45
45
|
CodeMailerSettings,
|
|
46
|
-
|
|
46
|
+
[
|
|
47
|
+
MailTransportFactory,
|
|
48
|
+
{
|
|
49
|
+
multiple: true
|
|
50
|
+
}
|
|
51
|
+
]
|
|
47
52
|
]
|
|
48
53
|
});
|
|
49
54
|
export { SaveSettingsUseCaseImplementation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SaveSettings/SaveSettingsUseCase.js","sources":["../../../src/features/SaveSettings/SaveSettingsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport {
|
|
1
|
+
{"version":3,"file":"features/SaveSettings/SaveSettingsUseCase.js","sources":["../../../src/features/SaveSettings/SaveSettingsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport {\n SaveSettingsUseCase,\n SaveSettingsRepository,\n type SaveSettingsInput\n} from \"./abstractions.js\";\nimport { MailerSettingsBeforeSaveEvent, MailerSettingsAfterSaveEvent } from \"./events.js\";\nimport { saveValidation } from \"./validation.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\n\nclass SaveSettingsUseCaseImpl implements SaveSettingsUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: SaveSettingsRepository.Interface,\n private codeSettings: CodeMailerSettings.Interface,\n private transportFactories: MailTransportFactory.Interface[]\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsUseCase.Return {\n const permission = await this.identityContext.getPermission(\"mailer.settings\");\n\n if (!permission) {\n return Result.fail(new SettingsNotAuthorized());\n }\n\n const validationResult = saveValidation.safeParse(input);\n if (!validationResult.success) {\n return Result.fail(new SettingsValidationError(validationResult.error.issues));\n }\n\n /* Refuse when any registered transport has code-defined settings. */\n const isLockedByCode = this.transportFactories.some(\n f => this.codeSettings.get(f.name) !== null\n );\n\n if (isLockedByCode) {\n return Result.fail(new SettingsLockedByCode());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _beforePassword, ...inputForEvent } = input;\n const beforeSaveEvent = new MailerSettingsBeforeSaveEvent({ input: inputForEvent });\n await this.eventPublisher.publish(beforeSaveEvent);\n\n const result = await this.repository.execute(input);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n const afterSaveEvent = new MailerSettingsAfterSaveEvent({ settings: result.value });\n await this.eventPublisher.publish(afterSaveEvent);\n\n return result;\n }\n}\n\nexport const SaveSettingsUseCaseImplementation = SaveSettingsUseCase.createImplementation({\n implementation: SaveSettingsUseCaseImpl,\n dependencies: [\n IdentityContext,\n EventPublisher,\n SaveSettingsRepository,\n CodeMailerSettings,\n [MailTransportFactory, { multiple: true }]\n ]\n});\n"],"names":["SaveSettingsUseCaseImpl","identityContext","eventPublisher","repository","codeSettings","transportFactories","input","permission","Result","SettingsNotAuthorized","validationResult","saveValidation","SettingsValidationError","isLockedByCode","f","SettingsLockedByCode","_beforePassword","inputForEvent","beforeSaveEvent","MailerSettingsBeforeSaveEvent","result","SettingsPersistenceError","afterSaveEvent","MailerSettingsAfterSaveEvent","SaveSettingsUseCaseImplementation","SaveSettingsUseCase","IdentityContext","EventPublisher","SaveSettingsRepository","CodeMailerSettings","MailTransportFactory"],"mappings":";;;;;;;;;AAmBA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA4C,EAC5CC,YAA0C,EAC1CC,kBAAoD,CAC9D;aALUJ,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;aACAC,kBAAkB,GAAlBA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAA8B;QAChE,MAAMC,aAAa,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;QAE5D,IAAI,CAACA,YACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,MAAMC,mBAAmBC,eAAe,SAAS,CAACL;QAClD,IAAI,CAACI,iBAAiB,OAAO,EACzB,OAAOF,OAAO,IAAI,CAAC,IAAII,wBAAwBF,iBAAiB,KAAK,CAAC,MAAM;QAIhF,MAAMG,iBAAiB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC/CC,CAAAA,IAAK,AAAkC,SAAlC,IAAI,CAAC,YAAY,CAAC,GAAG,CAACA,EAAE,IAAI;QAGrC,IAAID,gBACA,OAAOL,OAAO,IAAI,CAAC,IAAIO;QAI3B,MAAM,EAAE,UAAUC,eAAe,EAAE,GAAGC,eAAe,GAAGX;QACxD,MAAMY,kBAAkB,IAAIC,8BAA8B;YAAE,OAAOF;QAAc;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACC;QAElC,MAAME,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACd;QAE7C,IAAIc,OAAO,MAAM,IACb,OAAOZ,OAAO,IAAI,CAAC,IAAIa,yBAAyBD,OAAO,KAAK;QAGhE,MAAME,iBAAiB,IAAIC,6BAA6B;YAAE,UAAUH,OAAO,KAAK;QAAC;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACE;QAElC,OAAOF;IACX;AACJ;AAEO,MAAMI,oCAAoCC,oBAAoB,oBAAoB,CAAC;IACtF,gBAAgBzB;IAChB,cAAc;QACV0B;QACAC;QACAC;QACAC;QACA;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAC7C;AACL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SaveSettings/abstractions.js","sources":["../../../src/features/SaveSettings/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { DomainEvent, IEventHandler } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\n\nexport interface SaveSettingsInput {\n host: string;\n port?: number;\n user: string;\n password?: string;\n from: string;\n replyTo?: string;\n}\n\nexport interface ISaveSettingsErrors {\n validation: SettingsValidationError;\n persistence: SettingsPersistenceError;\n notAuthorized: SettingsNotAuthorized;\n lockedByCode: SettingsLockedByCode;\n}\n\ntype SaveSettingsError = ISaveSettingsErrors[keyof ISaveSettingsErrors];\n\n/**\n * Save-side returns are password-free. The only path that exposes the password\n * to in-process callers is GetSettingsRepository.get / GetSettingsUseCase.execute\n * (used by MailerService to authenticate SMTP). Everything else — events,\n * GraphQL responses, logs, audit trails — must use this Omit shape.\n */\nexport type SavedTransportSettings = Omit<TransportSettings, \"password\">;\n\nexport interface ISaveSettingsRepository {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsRepository =\n createAbstraction<ISaveSettingsRepository>(\"SaveSettingsRepository\");\n\nexport namespace SaveSettingsRepository {\n export type Interface = ISaveSettingsRepository;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\nexport interface ISaveSettings {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsUseCase = createAbstraction<ISaveSettings>(\"SaveSettingsUseCase\");\n\nexport namespace SaveSettingsUseCase {\n export type Interface = ISaveSettings;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\n// Domain Events. Both payloads exclude `password` so subscribers (audit logs,\n// telemetry, etc.) cannot accidentally persist plaintext or ciphertext secrets.\nexport interface MailerSettingsBeforeSavePayload {\n input: Omit<SaveSettingsInput, \"password\">;\n}\n\nexport interface MailerSettingsAfterSavePayload {\n settings: Omit<TransportSettings, \"password\">;\n}\n\n// Event Handler Abstractions\nexport const MailerSettingsBeforeSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>\n>(\"MailerSettingsBeforeSaveEventHandler\");\n\nexport namespace MailerSettingsBeforeSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>;\n export type Event = DomainEvent<MailerSettingsBeforeSavePayload>;\n}\n\nexport const MailerSettingsAfterSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>\n>(\"MailerSettingsAfterSaveEventHandler\");\n\nexport namespace MailerSettingsAfterSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>;\n export type Event = DomainEvent<MailerSettingsAfterSavePayload>;\n}\n"],"names":["SaveSettingsRepository","createAbstraction","SaveSettingsUseCase","MailerSettingsBeforeSaveEventHandler","MailerSettingsAfterSaveEventHandler"],"mappings":";
|
|
1
|
+
{"version":3,"file":"features/SaveSettings/abstractions.js","sources":["../../../src/features/SaveSettings/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { DomainEvent, IEventHandler } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\n\nexport interface SaveSettingsInput {\n host: string;\n port?: number;\n secure?: boolean;\n user: string;\n password?: string;\n from: string;\n replyTo?: string;\n}\n\nexport interface ISaveSettingsErrors {\n validation: SettingsValidationError;\n persistence: SettingsPersistenceError;\n notAuthorized: SettingsNotAuthorized;\n lockedByCode: SettingsLockedByCode;\n}\n\ntype SaveSettingsError = ISaveSettingsErrors[keyof ISaveSettingsErrors];\n\n/**\n * Save-side returns are password-free. The only path that exposes the password\n * to in-process callers is GetSettingsRepository.get / GetSettingsUseCase.execute\n * (used by MailerService to authenticate SMTP). Everything else — events,\n * GraphQL responses, logs, audit trails — must use this Omit shape.\n */\nexport type SavedTransportSettings = Omit<TransportSettings, \"password\">;\n\nexport interface ISaveSettingsRepository {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsRepository =\n createAbstraction<ISaveSettingsRepository>(\"SaveSettingsRepository\");\n\nexport namespace SaveSettingsRepository {\n export type Interface = ISaveSettingsRepository;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\nexport interface ISaveSettings {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsUseCase = createAbstraction<ISaveSettings>(\"SaveSettingsUseCase\");\n\nexport namespace SaveSettingsUseCase {\n export type Interface = ISaveSettings;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\n// Domain Events. Both payloads exclude `password` so subscribers (audit logs,\n// telemetry, etc.) cannot accidentally persist plaintext or ciphertext secrets.\nexport interface MailerSettingsBeforeSavePayload {\n input: Omit<SaveSettingsInput, \"password\">;\n}\n\nexport interface MailerSettingsAfterSavePayload {\n settings: Omit<TransportSettings, \"password\">;\n}\n\n// Event Handler Abstractions\nexport const MailerSettingsBeforeSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>\n>(\"MailerSettingsBeforeSaveEventHandler\");\n\nexport namespace MailerSettingsBeforeSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>;\n export type Event = DomainEvent<MailerSettingsBeforeSavePayload>;\n}\n\nexport const MailerSettingsAfterSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>\n>(\"MailerSettingsAfterSaveEventHandler\");\n\nexport namespace MailerSettingsAfterSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>;\n export type Event = DomainEvent<MailerSettingsAfterSavePayload>;\n}\n"],"names":["SaveSettingsRepository","createAbstraction","SaveSettingsUseCase","MailerSettingsBeforeSaveEventHandler","MailerSettingsAfterSaveEventHandler"],"mappings":";AA0CO,MAAMA,yBACTC,kBAA2C;AAYxC,MAAMC,sBAAsBD,kBAAiC;AAmB7D,MAAME,uCAAuCF,kBAElD;AAOK,MAAMG,sCAAsCH,kBAEjD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import zod from "zod";
|
|
2
2
|
export declare const saveValidation: zod.ZodObject<{
|
|
3
|
+
secure: zod.ZodOptional<zod.ZodBoolean>;
|
|
3
4
|
password: zod.ZodPipe<zod.ZodOptional<zod.ZodOptional<zod.ZodNullable<zod.ZodString>>>, zod.ZodTransform<string | null, string | null | undefined>>;
|
|
4
5
|
from: zod.ZodString;
|
|
5
6
|
port: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodNumber>>>;
|
|
@@ -13,6 +13,7 @@ const common = {
|
|
|
13
13
|
};
|
|
14
14
|
const saveValidation = zod.object({
|
|
15
15
|
...common,
|
|
16
|
+
secure: zod.boolean().optional().describe("Use TLS/SSL"),
|
|
16
17
|
password: validation_password.nullish().optional().transform((value)=>void 0 === value ? null : value)
|
|
17
18
|
});
|
|
18
19
|
export { saveValidation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SaveSettings/validation.js","sources":["../../../src/features/SaveSettings/validation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { isMailboxAddress } from \"~/utils/isMailboxAddress.js\";\n\nconst password = zod.string().describe(\"Password\");\n\nconst mailboxAddress = zod.string().refine(isMailboxAddress, { message: \"Invalid email address.\" });\n\nconst common = {\n from: mailboxAddress.describe(\"Mail from\"),\n port: zod.number().optional().nullish().describe(\"Port\"),\n replyTo: zod\n .preprocess(\n // We need to set empty strings to `null` before address validation kicks in.\n value => (value === \"\" ? null : value),\n mailboxAddress.optional().nullish()\n )\n .describe(\"Mail reply-to\"),\n host: zod.string().describe(\"Hostname\"),\n user: zod.string().describe(\"User\")\n};\n\nexport const saveValidation = zod.object({\n ...common,\n password: password\n .nullish()\n .optional()\n .transform(value => {\n return value === undefined ? null : value;\n })\n});\n"],"names":["password","zod","mailboxAddress","isMailboxAddress","common","value","saveValidation","undefined"],"mappings":";;AAGA,MAAMA,sBAAWC,IAAI,MAAM,GAAG,QAAQ,CAAC;AAEvC,MAAMC,iBAAiBD,IAAI,MAAM,GAAG,MAAM,CAACE,kBAAkB;IAAE,SAAS;AAAyB;AAEjG,MAAMC,SAAS;IACX,MAAMF,eAAe,QAAQ,CAAC;IAC9B,MAAMD,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACjD,SAASA,IAAAA,UACM,CAEPI,CAAAA,QAAUA,AAAU,OAAVA,QAAe,OAAOA,OAChCH,eAAe,QAAQ,GAAG,OAAO,IAEpC,QAAQ,CAAC;IACd,MAAMD,IAAI,MAAM,GAAG,QAAQ,CAAC;IAC5B,MAAMA,IAAI,MAAM,GAAG,QAAQ,CAAC;AAChC;AAEO,MAAMK,iBAAiBL,IAAI,MAAM,CAAC;IACrC,GAAGG,MAAM;IACT,
|
|
1
|
+
{"version":3,"file":"features/SaveSettings/validation.js","sources":["../../../src/features/SaveSettings/validation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { isMailboxAddress } from \"~/utils/isMailboxAddress.js\";\n\nconst password = zod.string().describe(\"Password\");\n\nconst mailboxAddress = zod.string().refine(isMailboxAddress, { message: \"Invalid email address.\" });\n\nconst common = {\n from: mailboxAddress.describe(\"Mail from\"),\n port: zod.number().optional().nullish().describe(\"Port\"),\n replyTo: zod\n .preprocess(\n // We need to set empty strings to `null` before address validation kicks in.\n value => (value === \"\" ? null : value),\n mailboxAddress.optional().nullish()\n )\n .describe(\"Mail reply-to\"),\n host: zod.string().describe(\"Hostname\"),\n user: zod.string().describe(\"User\")\n};\n\nexport const saveValidation = zod.object({\n ...common,\n secure: zod.boolean().optional().describe(\"Use TLS/SSL\"),\n password: password\n .nullish()\n .optional()\n .transform(value => {\n return value === undefined ? null : value;\n })\n});\n"],"names":["password","zod","mailboxAddress","isMailboxAddress","common","value","saveValidation","undefined"],"mappings":";;AAGA,MAAMA,sBAAWC,IAAI,MAAM,GAAG,QAAQ,CAAC;AAEvC,MAAMC,iBAAiBD,IAAI,MAAM,GAAG,MAAM,CAACE,kBAAkB;IAAE,SAAS;AAAyB;AAEjG,MAAMC,SAAS;IACX,MAAMF,eAAe,QAAQ,CAAC;IAC9B,MAAMD,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACjD,SAASA,IAAAA,UACM,CAEPI,CAAAA,QAAUA,AAAU,OAAVA,QAAe,OAAOA,OAChCH,eAAe,QAAQ,GAAG,OAAO,IAEpC,QAAQ,CAAC;IACd,MAAMD,IAAI,MAAM,GAAG,QAAQ,CAAC;IAC5B,MAAMA,IAAI,MAAM,GAAG,QAAQ,CAAC;AAChC;AAEO,MAAMK,iBAAiBL,IAAI,MAAM,CAAC;IACrC,GAAGG,MAAM;IACT,QAAQH,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAUD,oBACL,OAAO,GACP,QAAQ,GACR,SAAS,CAACK,CAAAA,QACAA,AAAUE,WAAVF,QAAsB,OAAOA;AAEhD"}
|
|
@@ -8,7 +8,7 @@ declare class SendMailUseCaseImpl implements SendMailUseCase.Interface {
|
|
|
8
8
|
private mailerService;
|
|
9
9
|
private eventPublisher;
|
|
10
10
|
constructor(mailerService: MailerService.Interface, eventPublisher: EventPublisherAbstraction.Interface);
|
|
11
|
-
execute(data: TransportSendData): Promise<Result<never, MailValidationError> | Result<import("~/types.js").TransportSendResponse<any>, import("../../domain/MailerService/errors.js").NoTransportAvailableError | import("../../domain/MailerService/errors.js").
|
|
11
|
+
execute(data: TransportSendData): Promise<Result<never, MailValidationError> | Result<import("~/types.js").TransportSendResponse<any>, import("../../domain/MailerService/errors.js").NoTransportAvailableError | import("../../domain/MailerService/errors.js").TransportCreateError | import("../../domain/MailerService/errors.js").TransportSendError>>;
|
|
12
12
|
}
|
|
13
13
|
export declare const SendMailUseCaseImplementation: typeof SendMailUseCaseImpl & {
|
|
14
14
|
__abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ISendMailUseCase>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SmtpTransport/SmtpConfig.js","sources":["../../../src/features/SmtpTransport/SmtpConfig.ts"],"sourcesContent":["import type { TransportSettings } from \"~/types.js\";\nimport type SMTPTransport from \"nodemailer/lib/smtp-transport\";\n\nexport type SmtpTransportConfig = SMTPTransport.Options;\n\nconst configDefaults: Partial<SmtpTransportConfig> = {\n socketTimeout: 15000,\n connectionTimeout: 15000,\n greetingTimeout: 15000\n};\n\nexport class SmtpConfig {\n static fromTransportSettings(settings: TransportSettings): SmtpTransportConfig {\n const baseConfig: SmtpTransportConfig = {\n host: settings.host,\n port: settings.port,\n auth: {\n user: settings.user,\n pass: settings.password\n }\n };\n\n // Apply defaults\n return Object.keys(configDefaults).reduce<SmtpTransportConfig>((config, key) => {\n const configKey = key as keyof SmtpTransportConfig;\n if (config[configKey] === undefined || config[configKey] === null) {\n // @ts-expect-error\n config[configKey] = configDefaults[configKey];\n }\n return config;\n }, baseConfig);\n }\n}\n"],"names":["configDefaults","SmtpConfig","settings","baseConfig","Object","config","key","configKey","undefined"],"mappings":"AAKA,MAAMA,iBAA+C;IACjD,eAAe;IACf,mBAAmB;IACnB,iBAAiB;AACrB;AAEO,MAAMC;IACT,OAAO,sBAAsBC,QAA2B,EAAuB;QAC3E,MAAMC,aAAkC;YACpC,MAAMD,SAAS,IAAI;YACnB,MAAMA,SAAS,IAAI;YACnB,MAAM;gBACF,MAAMA,SAAS,IAAI;gBACnB,MAAMA,SAAS,QAAQ;YAC3B;QACJ;QAGA,OAAOE,OAAO,IAAI,CAACJ,gBAAgB,MAAM,CAAsB,CAACK,QAAQC;YACpE,MAAMC,YAAYD;YAClB,IAAID,AAAsBG,WAAtBH,MAAM,CAACE,UAAU,IAAkBF,AAAsB,SAAtBA,MAAM,CAACE,UAAU,EAEpDF,MAAM,CAACE,UAAU,GAAGP,cAAc,CAACO,UAAU;YAEjD,OAAOF;QACX,GAAGF;IACP;AACJ"}
|
|
1
|
+
{"version":3,"file":"features/SmtpTransport/SmtpConfig.js","sources":["../../../src/features/SmtpTransport/SmtpConfig.ts"],"sourcesContent":["import type { TransportSettings } from \"~/types.js\";\nimport type SMTPTransport from \"nodemailer/lib/smtp-transport\";\n\nexport type SmtpTransportConfig = SMTPTransport.Options;\n\nconst configDefaults: Partial<SmtpTransportConfig> = {\n socketTimeout: 15000,\n connectionTimeout: 15000,\n greetingTimeout: 15000\n};\n\nexport class SmtpConfig {\n static fromTransportSettings(settings: TransportSettings): SmtpTransportConfig {\n const baseConfig: SmtpTransportConfig = {\n host: settings.host,\n port: settings.port,\n secure: settings.secure,\n auth: {\n user: settings.user,\n pass: settings.password\n }\n };\n\n // Apply defaults\n return Object.keys(configDefaults).reduce<SmtpTransportConfig>((config, key) => {\n const configKey = key as keyof SmtpTransportConfig;\n if (config[configKey] === undefined || config[configKey] === null) {\n // @ts-expect-error\n config[configKey] = configDefaults[configKey];\n }\n return config;\n }, baseConfig);\n }\n}\n"],"names":["configDefaults","SmtpConfig","settings","baseConfig","Object","config","key","configKey","undefined"],"mappings":"AAKA,MAAMA,iBAA+C;IACjD,eAAe;IACf,mBAAmB;IACnB,iBAAiB;AACrB;AAEO,MAAMC;IACT,OAAO,sBAAsBC,QAA2B,EAAuB;QAC3E,MAAMC,aAAkC;YACpC,MAAMD,SAAS,IAAI;YACnB,MAAMA,SAAS,IAAI;YACnB,QAAQA,SAAS,MAAM;YACvB,MAAM;gBACF,MAAMA,SAAS,IAAI;gBACnB,MAAMA,SAAS,QAAQ;YAC3B;QACJ;QAGA,OAAOE,OAAO,IAAI,CAACJ,gBAAgB,MAAM,CAAsB,CAACK,QAAQC;YACpE,MAAMC,YAAYD;YAClB,IAAID,AAAsBG,WAAtBH,MAAM,CAACE,UAAU,IAAkBF,AAAsB,SAAtBA,MAAM,CAACE,UAAU,EAEpDF,MAAM,CAACE,UAAU,GAAGP,cAAc,CAACO,UAAU;YAEjD,OAAOF;QACX,GAAGF;IACP;AACJ"}
|
|
@@ -2,6 +2,7 @@ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js
|
|
|
2
2
|
import type { TransportSettings } from "../../types.js";
|
|
3
3
|
declare class SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {
|
|
4
4
|
readonly name = "Mailer/SmtpTransport";
|
|
5
|
+
canUse(settings: TransportSettings | null): boolean;
|
|
5
6
|
createTransport(settings: TransportSettings): MailTransportFactory.Return;
|
|
6
7
|
}
|
|
7
8
|
export declare const SmtpMailTransportFactory: typeof SmtpMailTransportFactoryImpl & {
|
|
@@ -2,6 +2,9 @@ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js
|
|
|
2
2
|
import { SmtpMailTransport } from "./SmtpMailTransport.js";
|
|
3
3
|
import { SmtpConfig } from "./SmtpConfig.js";
|
|
4
4
|
class SmtpMailTransportFactoryImpl {
|
|
5
|
+
canUse(settings) {
|
|
6
|
+
return null !== settings;
|
|
7
|
+
}
|
|
5
8
|
async createTransport(settings) {
|
|
6
9
|
return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));
|
|
7
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/SmtpTransport/SmtpMailTransportFactory.js","sources":["../../../src/features/SmtpTransport/SmtpMailTransportFactory.ts"],"sourcesContent":["import { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SmtpMailTransport } from \"~/features/SmtpTransport/SmtpMailTransport.js\";\nimport { SmtpConfig } from \"~/features/SmtpTransport/SmtpConfig.js\";\n\nclass SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/SmtpTransport\";\n\n async createTransport(settings: TransportSettings): MailTransportFactory.Return {\n return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));\n }\n}\n\nexport const SmtpMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: SmtpMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["SmtpMailTransportFactoryImpl","settings","SmtpMailTransport","SmtpConfig","SmtpMailTransportFactory","MailTransportFactory"],"mappings":";;;AAKA,MAAMA;IAGF,MAAM,
|
|
1
|
+
{"version":3,"file":"features/SmtpTransport/SmtpMailTransportFactory.js","sources":["../../../src/features/SmtpTransport/SmtpMailTransportFactory.ts"],"sourcesContent":["import { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SmtpMailTransport } from \"~/features/SmtpTransport/SmtpMailTransport.js\";\nimport { SmtpConfig } from \"~/features/SmtpTransport/SmtpConfig.js\";\n\nclass SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/SmtpTransport\";\n\n canUse(settings: TransportSettings | null): boolean {\n return settings !== null;\n }\n\n async createTransport(settings: TransportSettings): MailTransportFactory.Return {\n return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));\n }\n}\n\nexport const SmtpMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: SmtpMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["SmtpMailTransportFactoryImpl","settings","SmtpMailTransport","SmtpConfig","SmtpMailTransportFactory","MailTransportFactory"],"mappings":";;;AAKA,MAAMA;IAGF,OAAOC,QAAkC,EAAW;QAChD,OAAOA,AAAa,SAAbA;IACX;IAEA,MAAM,gBAAgBA,QAA2B,EAA+B;QAC5E,OAAO,IAAIC,kBAAkBC,WAAW,qBAAqB,CAACF;IAClE;;aARgB,IAAI,GAAG;;AAS3B;AAEO,MAAMG,2BAA2BC,qBAAqB,oBAAoB,CAAC;IAC9E,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
|
package/graphql/settings.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ErrorResponse, GraphQLSchemaPlugin } from "@webiny/handler-graphql";
|
|
2
2
|
import { GetSettingsUseCase } from "../features/GetSettings/abstractions.js";
|
|
3
3
|
import { SaveSettingsUseCase } from "../features/SaveSettings/abstractions.js";
|
|
4
|
-
|
|
4
|
+
const SMTP_TRANSPORT_NAME = "Mailer/SmtpTransport";
|
|
5
5
|
const emptyResolver = ()=>({});
|
|
6
6
|
const toPublicSettings = (settings, source)=>{
|
|
7
7
|
if (!settings) return null;
|
|
@@ -22,6 +22,7 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
|
|
|
22
22
|
type MailerTransportSettings {
|
|
23
23
|
host: String
|
|
24
24
|
port: Number
|
|
25
|
+
secure: Boolean
|
|
25
26
|
user: String
|
|
26
27
|
from: String
|
|
27
28
|
replyTo: String
|
|
@@ -40,6 +41,7 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
|
|
|
40
41
|
input MailerTransportSettingsInput {
|
|
41
42
|
host: String!
|
|
42
43
|
port: Number
|
|
44
|
+
secure: Boolean
|
|
43
45
|
user: String!
|
|
44
46
|
password: String
|
|
45
47
|
from: String!
|
|
@@ -64,14 +66,8 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
|
|
|
64
66
|
MailerQuery: {
|
|
65
67
|
getSettings: async (_, __, context)=>{
|
|
66
68
|
try {
|
|
67
|
-
const activeTransport = context.container.resolve(ActiveTransport);
|
|
68
|
-
const transportName = activeTransport.name();
|
|
69
|
-
if (!transportName) return {
|
|
70
|
-
data: null,
|
|
71
|
-
error: null
|
|
72
|
-
};
|
|
73
69
|
const getSettings = context.container.resolve(GetSettingsUseCase);
|
|
74
|
-
const result = await getSettings.execute(
|
|
70
|
+
const result = await getSettings.execute(SMTP_TRANSPORT_NAME);
|
|
75
71
|
const { settings, source } = result.value;
|
|
76
72
|
return {
|
|
77
73
|
data: toPublicSettings(settings, source),
|
package/graphql/settings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql/settings.js","sources":["../../src/graphql/settings.ts"],"sourcesContent":["import { ErrorResponse, GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\nimport { GetSettingsUseCase } from \"~/features/GetSettings/abstractions.js\";\nimport { SaveSettingsUseCase } from \"~/features/SaveSettings/abstractions.js\";\nimport
|
|
1
|
+
{"version":3,"file":"graphql/settings.js","sources":["../../src/graphql/settings.ts"],"sourcesContent":["import { ErrorResponse, GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\nimport { GetSettingsUseCase } from \"~/features/GetSettings/abstractions.js\";\nimport { SaveSettingsUseCase } from \"~/features/SaveSettings/abstractions.js\";\nimport type { MailerSettingsSource } from \"~/features/GetSettings/abstractions.js\";\nimport type { Context } from \"@webiny/api/types.js\";\nimport type { TransportSettings } from \"~/types.js\";\n\nconst SMTP_TRANSPORT_NAME = \"Mailer/SmtpTransport\";\n\nconst emptyResolver = () => ({});\n\n// Strip `password` before the settings leave the server and tack on `source`\n// so the admin UI can branch on code-vs-storage. Accepts both the full\n// `TransportSettings` (from getSettings) and the already-stripped\n// `Omit<TransportSettings, \"password\">` (from saveSettings) — defense in depth\n// even when the input type carries no password to begin with.\nconst toPublicSettings = (\n settings: TransportSettings | Omit<TransportSettings, \"password\"> | null,\n source: MailerSettingsSource\n): (Omit<TransportSettings, \"password\"> & { source: MailerSettingsSource }) | null => {\n if (!settings) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...publicSettings } = settings as TransportSettings;\n return { ...publicSettings, source };\n};\n\nexport const createSettingsGraphQL = () => {\n return new GraphQLSchemaPlugin<Context>({\n typeDefs: `\n type MailerTransportSettingsError {\n message: String!\n code: String\n data: JSON\n }\n\n type MailerTransportSettings {\n host: String\n port: Number\n secure: Boolean\n user: String\n from: String\n replyTo: String\n source: String\n }\n\n type MailerTransportSettingsResponse {\n data: MailerTransportSettings\n error: MailerTransportSettingsError\n }\n\n type MailerQuery {\n getSettings: MailerTransportSettingsResponse!\n }\n\n input MailerTransportSettingsInput {\n host: String!\n port: Number\n secure: Boolean\n user: String!\n password: String\n from: String!\n replyTo: String\n }\n\n type MailerMutation {\n saveSettings(data: MailerTransportSettingsInput!): MailerTransportSettingsResponse!\n }\n\n extend type Query {\n mailer: MailerQuery\n }\n extend type Mutation {\n mailer: MailerMutation\n }\n `,\n resolvers: {\n Query: {\n mailer: emptyResolver\n },\n MailerQuery: {\n getSettings: async (_, __, context) => {\n try {\n const getSettings = context.container.resolve(GetSettingsUseCase);\n const result = await getSettings.execute(SMTP_TRANSPORT_NAME);\n\n const { settings, source } = result.value;\n\n return {\n data: toPublicSettings(settings, source),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n },\n Mutation: {\n mailer: emptyResolver\n },\n MailerMutation: {\n saveSettings: async (_, args: any, context) => {\n try {\n const saveSettings = context.container.resolve(SaveSettingsUseCase);\n const result = await saveSettings.execute(args.data);\n\n if (result.isFail()) {\n return new ErrorResponse(result.error);\n }\n\n return {\n data: toPublicSettings(result.value, \"storage\"),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n }\n }\n });\n};\n"],"names":["SMTP_TRANSPORT_NAME","emptyResolver","toPublicSettings","settings","source","_password","publicSettings","createSettingsGraphQL","GraphQLSchemaPlugin","_","__","context","getSettings","GetSettingsUseCase","result","ex","ErrorResponse","args","saveSettings","SaveSettingsUseCase"],"mappings":";;;AAOA,MAAMA,sBAAsB;AAE5B,MAAMC,gBAAgB,IAAO,EAAC;AAO9B,MAAMC,mBAAmB,CACrBC,UACAC;IAEA,IAAI,CAACD,UACD,OAAO;IAGX,MAAM,EAAE,UAAUE,SAAS,EAAE,GAAGC,gBAAgB,GAAGH;IACnD,OAAO;QAAE,GAAGG,cAAc;QAAEF;IAAO;AACvC;AAEO,MAAMG,wBAAwB,IAC1B,IAAIC,oBAA6B;QACpC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8CX,CAAC;QACD,WAAW;YACP,OAAO;gBACH,QAAQP;YACZ;YACA,aAAa;gBACT,aAAa,OAAOQ,GAAGC,IAAIC;oBACvB,IAAI;wBACA,MAAMC,cAAcD,QAAQ,SAAS,CAAC,OAAO,CAACE;wBAC9C,MAAMC,SAAS,MAAMF,YAAY,OAAO,CAACZ;wBAEzC,MAAM,EAAEG,QAAQ,EAAEC,MAAM,EAAE,GAAGU,OAAO,KAAK;wBAEzC,OAAO;4BACH,MAAMZ,iBAAiBC,UAAUC;4BACjC,OAAO;wBACX;oBACJ,EAAE,OAAOW,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;YACA,UAAU;gBACN,QAAQd;YACZ;YACA,gBAAgB;gBACZ,cAAc,OAAOQ,GAAGQ,MAAWN;oBAC/B,IAAI;wBACA,MAAMO,eAAeP,QAAQ,SAAS,CAAC,OAAO,CAACQ;wBAC/C,MAAML,SAAS,MAAMI,aAAa,OAAO,CAACD,KAAK,IAAI;wBAEnD,IAAIH,OAAO,MAAM,IACb,OAAO,IAAIE,cAAcF,OAAO,KAAK;wBAGzC,OAAO;4BACH,MAAMZ,iBAAiBY,OAAO,KAAK,EAAE;4BACrC,OAAO;wBACX;oBACJ,EAAE,OAAOC,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;QACJ;IACJ"}
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { MailerService } from "./domain/MailerService/abstractions.js";
|
|
2
2
|
export type { IMailerService, IMailerServiceErrors } from "./domain/MailerService/abstractions.js";
|
|
3
|
-
export declare const createMailerContext: () => import("@webiny/
|
|
3
|
+
export declare const createMailerContext: () => import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types.js").Context>;
|
|
4
4
|
export declare const createMailerGraphQL: () => import("@webiny/handler-graphql/index.js").GraphQLSchemaPlugin<import("@webiny/api/types.js").Context>;
|
package/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createContextPlugin } from "@webiny/api";
|
|
2
1
|
import { CodeMailerSettingsFeature } from "./features/CodeMailerSettings/feature.js";
|
|
3
2
|
import { GetSettingsFeature } from "./features/GetSettings/feature.js";
|
|
4
3
|
import { SaveSettingsFeature } from "./features/SaveSettings/feature.js";
|
|
@@ -7,7 +6,8 @@ import { SmtpTransportFeature } from "./features/SmtpTransport/feature.js";
|
|
|
7
6
|
import { MailerServiceFeature } from "./features/MailerService/feature.js";
|
|
8
7
|
import { SendMailFeature } from "./features/SendMail/feature.js";
|
|
9
8
|
import { createSettingsGraphQL } from "./graphql/settings.js";
|
|
10
|
-
|
|
9
|
+
import { createRegisterExtensionPlugin } from "@webiny/handler";
|
|
10
|
+
const createMailerContext = ()=>createRegisterExtensionPlugin((context)=>{
|
|
11
11
|
CodeMailerSettingsFeature.register(context.container);
|
|
12
12
|
DummyTransportFeature.register(context.container);
|
|
13
13
|
SmtpTransportFeature.register(context.container);
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { CodeMailerSettingsFeature } from \"~/features/CodeMailerSettings/feature.js\";\nimport { GetSettingsFeature } from \"~/features/GetSettings/feature.js\";\nimport { SaveSettingsFeature } from \"~/features/SaveSettings/feature.js\";\nimport { DummyTransportFeature } from \"~/features/DummyTransport/feature.js\";\nimport { SmtpTransportFeature } from \"~/features/SmtpTransport/feature.js\";\nimport { MailerServiceFeature } from \"~/features/MailerService/feature.js\";\nimport { SendMailFeature } from \"~/features/SendMail/feature.js\";\nimport { createSettingsGraphQL } from \"~/graphql/settings.js\";\nimport { createRegisterExtensionPlugin } from \"@webiny/handler\";\n\nexport { MailerService } from \"./domain/MailerService/abstractions.js\";\nexport type { IMailerService, IMailerServiceErrors } from \"./domain/MailerService/abstractions.js\";\n\nexport const createMailerContext = () => {\n return createRegisterExtensionPlugin(context => {\n // Register all features.\n CodeMailerSettingsFeature.register(context.container);\n DummyTransportFeature.register(context.container);\n SmtpTransportFeature.register(context.container);\n GetSettingsFeature.register(context.container);\n SaveSettingsFeature.register(context.container);\n MailerServiceFeature.register(context.container);\n SendMailFeature.register(context.container);\n });\n};\n\nexport const createMailerGraphQL = () => {\n return createSettingsGraphQL();\n};\n"],"names":["createMailerContext","createRegisterExtensionPlugin","context","CodeMailerSettingsFeature","DummyTransportFeature","SmtpTransportFeature","GetSettingsFeature","SaveSettingsFeature","MailerServiceFeature","SendMailFeature","createMailerGraphQL","createSettingsGraphQL"],"mappings":";;;;;;;;;AAaO,MAAMA,sBAAsB,IACxBC,8BAA8BC,CAAAA;QAEjCC,0BAA0B,QAAQ,CAACD,QAAQ,SAAS;QACpDE,sBAAsB,QAAQ,CAACF,QAAQ,SAAS;QAChDG,qBAAqB,QAAQ,CAACH,QAAQ,SAAS;QAC/CI,mBAAmB,QAAQ,CAACJ,QAAQ,SAAS;QAC7CK,oBAAoB,QAAQ,CAACL,QAAQ,SAAS;QAC9CM,qBAAqB,QAAQ,CAACN,QAAQ,SAAS;QAC/CO,gBAAgB,QAAQ,CAACP,QAAQ,SAAS;IAC9C;AAGG,MAAMQ,sBAAsB,IACxBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/api-mailer",
|
|
3
|
-
"version": "6.4.0-beta.
|
|
3
|
+
"version": "6.4.0-beta.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -18,33 +18,35 @@
|
|
|
18
18
|
"description": "The API to send e-mails.",
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@webiny/api": "6.4.0-beta.
|
|
22
|
-
"@webiny/api-headless-cms": "6.4.0-beta.
|
|
23
|
-
"@webiny/feature": "6.4.0-beta.
|
|
24
|
-
"@webiny/handler-graphql": "6.4.0-beta.
|
|
25
|
-
"@webiny/plugins": "6.4.0-beta.
|
|
21
|
+
"@webiny/api": "6.4.0-beta.5",
|
|
22
|
+
"@webiny/api-headless-cms": "6.4.0-beta.5",
|
|
23
|
+
"@webiny/feature": "6.4.0-beta.5",
|
|
24
|
+
"@webiny/handler-graphql": "6.4.0-beta.5",
|
|
25
|
+
"@webiny/plugins": "6.4.0-beta.5",
|
|
26
26
|
"email-addresses": "5.0.0",
|
|
27
|
-
"nodemailer": "8.0.
|
|
27
|
+
"nodemailer": "8.0.8",
|
|
28
28
|
"zod": "4.4.3"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/nodemailer": "8.0.0",
|
|
32
|
-
"@webiny/api-core": "6.4.0-beta.
|
|
33
|
-
"@webiny/build-tools": "6.4.0-beta.
|
|
34
|
-
"@webiny/db-dynamodb": "6.4.0-beta.
|
|
35
|
-
"@webiny/handler": "6.4.0-beta.
|
|
36
|
-
"@webiny/handler-aws": "6.4.0-beta.
|
|
37
|
-
"@webiny/handler-db": "6.4.0-beta.
|
|
38
|
-
"@webiny/project-utils": "6.4.0-beta.
|
|
32
|
+
"@webiny/api-core": "6.4.0-beta.5",
|
|
33
|
+
"@webiny/build-tools": "6.4.0-beta.5",
|
|
34
|
+
"@webiny/db-dynamodb": "6.4.0-beta.5",
|
|
35
|
+
"@webiny/handler": "6.4.0-beta.5",
|
|
36
|
+
"@webiny/handler-aws": "6.4.0-beta.5",
|
|
37
|
+
"@webiny/handler-db": "6.4.0-beta.5",
|
|
38
|
+
"@webiny/project-utils": "6.4.0-beta.5",
|
|
39
39
|
"graphql": "16.14.0",
|
|
40
40
|
"jest-dynalite": "3.6.1",
|
|
41
41
|
"rimraf": "6.1.3",
|
|
42
42
|
"typescript": "6.0.3",
|
|
43
|
-
"vitest": "4.1.
|
|
43
|
+
"vitest": "4.1.7"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
|
-
"access": "public"
|
|
47
|
-
"directory": "dist"
|
|
46
|
+
"access": "public"
|
|
48
47
|
},
|
|
49
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "8476da73b653c89cc1474d968baf55c1b0ae0e5f",
|
|
49
|
+
"webiny": {
|
|
50
|
+
"publishFrom": "dist"
|
|
51
|
+
}
|
|
50
52
|
}
|
package/types.d.ts
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ActiveTransport as ActiveTransportAbstraction, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
2
|
-
declare class ActiveTransportImpl implements ActiveTransportAbstraction.Interface {
|
|
3
|
-
private transportFactories;
|
|
4
|
-
constructor(transportFactories: MailTransportFactory.Interface[]);
|
|
5
|
-
name(): string | null;
|
|
6
|
-
}
|
|
7
|
-
export declare const ActiveTransport: typeof ActiveTransportImpl & {
|
|
8
|
-
__abstraction: import("@webiny/di").Abstraction<import("~/domain/MailTransport/abstractions.js").IActiveTransport>;
|
|
9
|
-
};
|
|
10
|
-
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { ActiveTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
|
|
2
|
-
class ActiveTransportImpl {
|
|
3
|
-
constructor(transportFactories){
|
|
4
|
-
this.transportFactories = transportFactories;
|
|
5
|
-
}
|
|
6
|
-
name() {
|
|
7
|
-
if (0 === this.transportFactories.length) return null;
|
|
8
|
-
return this.transportFactories[this.transportFactories.length - 1].name;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
const ActiveTransport_ActiveTransport = ActiveTransport.createImplementation({
|
|
12
|
-
implementation: ActiveTransportImpl,
|
|
13
|
-
dependencies: [
|
|
14
|
-
[
|
|
15
|
-
MailTransportFactory,
|
|
16
|
-
{
|
|
17
|
-
multiple: true
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
]
|
|
21
|
-
});
|
|
22
|
-
export { ActiveTransport_ActiveTransport as ActiveTransport };
|
|
23
|
-
|
|
24
|
-
//# sourceMappingURL=ActiveTransport.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"features/MailerService/ActiveTransport.js","sources":["../../../src/features/MailerService/ActiveTransport.ts"],"sourcesContent":["import {\n ActiveTransport as ActiveTransportAbstraction,\n MailTransportFactory\n} from \"~/domain/MailTransport/abstractions.js\";\n\nclass ActiveTransportImpl implements ActiveTransportAbstraction.Interface {\n constructor(private transportFactories: MailTransportFactory.Interface[]) {}\n\n name(): string | null {\n if (this.transportFactories.length === 0) {\n return null;\n }\n return this.transportFactories[this.transportFactories.length - 1].name;\n }\n}\n\nexport const ActiveTransport = ActiveTransportAbstraction.createImplementation({\n implementation: ActiveTransportImpl,\n dependencies: [[MailTransportFactory, { multiple: true }]]\n});\n"],"names":["ActiveTransportImpl","transportFactories","ActiveTransport","ActiveTransportAbstraction","MailTransportFactory"],"mappings":";AAKA,MAAMA;IACF,YAAoBC,kBAAoD,CAAE;aAAtDA,kBAAkB,GAAlBA;IAAuD;IAE3E,OAAsB;QAClB,IAAI,AAAmC,MAAnC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAC9B,OAAO;QAEX,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI;IAC3E;AACJ;AAEO,MAAMC,kCAAkBC,gBAAAA,oBAA+C,CAAC;IAC3E,gBAAgBH;IAChB,cAAc;QAAC;YAACI;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAAC;AAC9D"}
|