@fluojs/email 1.0.0-beta.5 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +14 -0
- package/README.md +14 -0
- package/dist/service.d.ts +1 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +19 -1
- package/package.json +7 -7
package/README.ko.md
CHANGED
|
@@ -301,10 +301,21 @@ email 패키지는 의도적으로 다음을 **포함하지 않습니다**:
|
|
|
301
301
|
|
|
302
302
|
### 계약과 헬퍼
|
|
303
303
|
|
|
304
|
+
- `Email`: `address`와 선택적 display `name`을 포함하는 정규화된 이메일 주소 값입니다.
|
|
305
|
+
- `EmailAddress` / `EmailAddressLike`: `EmailService`가 정규화하기 전에 허용하는 구조화 또는 축약 recipient 값입니다.
|
|
306
|
+
- `EmailModuleOptions` / `EmailAsyncModuleOptions`: sender 기본값, renderer, lifecycle 검증, transport factory wiring을 포함하는 동기/비동기 모듈 등록 계약입니다.
|
|
304
307
|
- `EmailMessage`
|
|
308
|
+
- `EmailNotificationDispatchRequest` / `EmailNotificationPayload`: `EmailChannel`이 소비하는 notification channel payload 계약입니다.
|
|
309
|
+
- `EmailSendOptions` / `EmailSendManyOptions`: abort signal과 batch failure 수집 같은 per-send 제어 옵션입니다.
|
|
310
|
+
- `EmailSendResult` / `EmailSendBatchResult` / `EmailSendFailure`: accepted, pending, rejected, failed message를 보존하는 직접/배치 전달 결과 계약입니다.
|
|
311
|
+
- `EmailTransportReceipt`: `EmailSendResult`에 보존되는 transport-level provider receipt입니다.
|
|
305
312
|
- `EmailTransport`
|
|
313
|
+
- `EmailTransportContext`
|
|
306
314
|
- `EmailTransportFactory`
|
|
315
|
+
- `EmailTemplateRenderInput`
|
|
307
316
|
- `EmailTemplateRenderer`
|
|
317
|
+
- `EmailTemplateRenderResult`
|
|
318
|
+
- `NormalizedEmailAddressList` / `NormalizedEmailMessage`: typed integration과 테스트를 위해 노출되는 내부 정규화 message shape입니다.
|
|
308
319
|
|
|
309
320
|
### 통합 서브패스
|
|
310
321
|
|
|
@@ -313,6 +324,9 @@ email 패키지는 의도적으로 다음을 **포함하지 않습니다**:
|
|
|
313
324
|
### 상태 및 에러
|
|
314
325
|
|
|
315
326
|
- `createEmailPlatformStatusSnapshot(...)`
|
|
327
|
+
- `EmailLifecycleState`
|
|
328
|
+
- `EmailPlatformStatusSnapshot`
|
|
329
|
+
- `EmailStatusAdapterInput`
|
|
316
330
|
- `EmailConfigurationError`
|
|
317
331
|
- `EmailLifecycleError`: lifecycle로 차단된 전달, transport 초기화 또는 검증, 소유 리소스 shutdown 실패에서 발생합니다. 애플리케이션 teardown과 전송이 경합할 수 있다면 이 에러를 catch하세요.
|
|
318
332
|
- `EmailMessageValidationError`
|
package/README.md
CHANGED
|
@@ -301,10 +301,21 @@ These limitations are part of the package contract so transport selection, templ
|
|
|
301
301
|
|
|
302
302
|
### Contracts and helpers
|
|
303
303
|
|
|
304
|
+
- `Email`: Normalized email address value with an `address` and optional display `name`.
|
|
305
|
+
- `EmailAddress` / `EmailAddressLike`: Structured or shorthand recipient values accepted by `EmailService` before normalization.
|
|
306
|
+
- `EmailModuleOptions` / `EmailAsyncModuleOptions`: Synchronous and async module registration contracts, including sender defaults, renderer, lifecycle verification, and transport factory wiring.
|
|
304
307
|
- `EmailMessage`
|
|
308
|
+
- `EmailNotificationDispatchRequest` / `EmailNotificationPayload`: Notification channel payload contracts consumed by `EmailChannel`.
|
|
309
|
+
- `EmailSendOptions` / `EmailSendManyOptions`: Per-send controls such as abort signals and batch failure collection.
|
|
310
|
+
- `EmailSendResult` / `EmailSendBatchResult` / `EmailSendFailure`: Direct and batch delivery result contracts that preserve accepted, pending, rejected, and failed messages.
|
|
311
|
+
- `EmailTransportReceipt`: Transport-level provider receipt preserved by `EmailSendResult`.
|
|
305
312
|
- `EmailTransport`
|
|
313
|
+
- `EmailTransportContext`
|
|
306
314
|
- `EmailTransportFactory`
|
|
315
|
+
- `EmailTemplateRenderInput`
|
|
307
316
|
- `EmailTemplateRenderer`
|
|
317
|
+
- `EmailTemplateRenderResult`
|
|
318
|
+
- `NormalizedEmailAddressList` / `NormalizedEmailMessage`: Internal-normalized message shapes exposed for typed integrations and tests.
|
|
308
319
|
|
|
309
320
|
### Integration subpaths
|
|
310
321
|
|
|
@@ -313,6 +324,9 @@ These limitations are part of the package contract so transport selection, templ
|
|
|
313
324
|
### Status and errors
|
|
314
325
|
|
|
315
326
|
- `createEmailPlatformStatusSnapshot(...)`
|
|
327
|
+
- `EmailLifecycleState`
|
|
328
|
+
- `EmailPlatformStatusSnapshot`
|
|
329
|
+
- `EmailStatusAdapterInput`
|
|
316
330
|
- `EmailConfigurationError`
|
|
317
331
|
- `EmailLifecycleError`: thrown by lifecycle-gated delivery, transport initialization or verification, and owned-resource shutdown failures. Catch this error when sends can race with application teardown.
|
|
318
332
|
- `EmailMessageValidationError`
|
package/dist/service.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export declare class EmailService implements Email, OnModuleInit, OnApplicationS
|
|
|
77
77
|
*/
|
|
78
78
|
sendNotification(notification: EmailNotificationDispatchRequest, options?: EmailSendOptions): Promise<EmailSendResult>;
|
|
79
79
|
private ensureTransport;
|
|
80
|
+
private clearResolvedTransport;
|
|
80
81
|
private ensureReadyForDelivery;
|
|
81
82
|
private getLifecycleState;
|
|
82
83
|
private assertCanCreateOrUseTransport;
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM3E,OAAO,KAAK,EACV,KAAK,EAGL,YAAY,EACZ,gCAAgC,EAChC,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EAKf,4BAA4B,EAC7B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM3E,OAAO,KAAK,EACV,KAAK,EAGL,YAAY,EACZ,gCAAgC,EAChC,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EAKf,4BAA4B,EAC7B,MAAM,YAAY,CAAC;AA4EpB;;;;;;;GAOG;AACH,qBACa,YAAa,YAAW,KAAK,EAAE,YAAY,EAAE,qBAAqB;IAMjE,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,gBAAgB,CAAsC;gBAEjC,OAAO,EAAE,4BAA4B;IAE5D,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBtC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBrB,cAAc;IA+C5B;;;;OAIG;IACH,4BAA4B;IAY5B;;;;;;;;;;;;;;;;;OAiBG;IACG,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6B3F;;;;;;;;;;;;OAYG;IACG,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA6BpH;;;;;;;;;;;;;;;;;OAiBG;IACG,gBAAgB,CACpB,YAAY,EAAE,gCAAgC,EAC9C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC;YA+Bb,eAAe;IAiB7B,OAAO,CAAC,sBAAsB;YAKhB,sBAAsB;IAwBpC,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,gBAAgB;YAuBV,kBAAkB;CAkBjC"}
|
package/dist/service.js
CHANGED
|
@@ -48,6 +48,9 @@ function createLifecycleError(message, cause) {
|
|
|
48
48
|
function createDeliveryLifecycleError(state) {
|
|
49
49
|
return new EmailLifecycleError(`Email delivery cannot start while the service lifecycle is ${state}.`);
|
|
50
50
|
}
|
|
51
|
+
function createCleanupFailureCause(originalError, cleanupError) {
|
|
52
|
+
return new AggregateError([originalError, cleanupError], 'Email transport verification failed and the owned transport failed to close.');
|
|
53
|
+
}
|
|
51
54
|
function isShutdownLifecycleState(state) {
|
|
52
55
|
return state === 'stopping' || state === 'stopped';
|
|
53
56
|
}
|
|
@@ -134,7 +137,18 @@ class EmailService {
|
|
|
134
137
|
throw error;
|
|
135
138
|
}
|
|
136
139
|
this.lifecycleState = 'failed';
|
|
137
|
-
|
|
140
|
+
let cause = error;
|
|
141
|
+
const transport = this.resolvedTransport;
|
|
142
|
+
if (transport && this.options.transport.ownsResources && transport.close) {
|
|
143
|
+
try {
|
|
144
|
+
await transport.close();
|
|
145
|
+
} catch (cleanupError) {
|
|
146
|
+
cause = createCleanupFailureCause(error, cleanupError);
|
|
147
|
+
} finally {
|
|
148
|
+
this.clearResolvedTransport();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
throw createLifecycleError('Email transport failed to initialize.', cause);
|
|
138
152
|
}
|
|
139
153
|
}
|
|
140
154
|
|
|
@@ -295,6 +309,10 @@ class EmailService {
|
|
|
295
309
|
}
|
|
296
310
|
return this.transportPromise;
|
|
297
311
|
}
|
|
312
|
+
clearResolvedTransport() {
|
|
313
|
+
this.resolvedTransport = undefined;
|
|
314
|
+
this.transportPromise = undefined;
|
|
315
|
+
}
|
|
298
316
|
async ensureReadyForDelivery() {
|
|
299
317
|
this.assertCanDeliver();
|
|
300
318
|
if (!this.options.verifyOnModuleInit) {
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"queue",
|
|
11
11
|
"mailer"
|
|
12
12
|
],
|
|
13
|
-
"version": "1.0.
|
|
13
|
+
"version": "1.0.1",
|
|
14
14
|
"private": false,
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
"dist"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@fluojs/core": "^1.0.
|
|
56
|
-
"@fluojs/
|
|
57
|
-
"@fluojs/
|
|
58
|
-
"@fluojs/runtime": "^1.
|
|
55
|
+
"@fluojs/core": "^1.0.3",
|
|
56
|
+
"@fluojs/di": "^1.0.3",
|
|
57
|
+
"@fluojs/notifications": "^1.0.1",
|
|
58
|
+
"@fluojs/runtime": "^1.1.1"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"nodemailer": "^6.10.1",
|
|
62
|
-
"@fluojs/queue": "^1.0.0
|
|
62
|
+
"@fluojs/queue": "^1.0.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependenciesMeta": {
|
|
65
65
|
"@fluojs/queue": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/nodemailer": "^8.0.0",
|
|
74
74
|
"vitest": "^3.2.4",
|
|
75
|
-
"@fluojs/queue": "^1.0.0
|
|
75
|
+
"@fluojs/queue": "^1.0.0"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|