Lettermint transport#23
Conversation
Add a new @upyo/lettermint package with configuration helpers, message conversion, HTTP API delivery, batching, retry handling, and cross-runtime tests. The transport preserves attachment MIME types, retries provider request timeouts, and streams sendMany() input in Lettermint-sized chunks. Document the new transport in the package README, the VitePress docs, the root package table, and CHANGES.md, and wire it into the workspace and documentation build. Fixes #22 Assisted-by: Codex:gpt-5.5
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #23 +/- ##
==========================================
+ Coverage 75.80% 76.57% +0.77%
==========================================
Files 76 81 +5
Lines 6767 7344 +577
Branches 1065 1205 +140
==========================================
+ Hits 5130 5624 +494
- Misses 1310 1361 +51
- Partials 327 359 +32 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding support for the Lettermint transactional email provider to the Upyo library. The implementation includes a LettermintTransport class that handles single and batch sends, idempotency, and provider-specific features like routes and metadata. Feedback focuses on simplifying the sendMany implementation, improving reliability by retrying on rate-limit errors (HTTP 429), ensuring RFC 5322 compliance by escaping backslashes in email addresses, and optimizing performance by moving the standard headers set to a module-level constant.
Retry rate-limited Lettermint responses so transient 429 errors follow the configured retry policy. Also simplify sendMany() to use one async iteration path, escape backslashes in display names, and reuse the standard-header set across message conversions. #23 (comment) #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
/gemini review |
|
@codex review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, providing a transport implementation for the Lettermint HTTP API with support for single and batch sends, idempotency, and tracking settings. The review feedback identifies several technical improvements, including simplifying signal combination using native AbortSignal.any, addressing a memory leak in the sleep utility by ensuring event listeners are removed, and optimizing base64 encoding for attachments to improve performance.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4973b6e8f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Exercise Lettermint attachment delivery alongside the existing text, HTML, and batch scenarios. The E2E tests now run serially, wait briefly between API calls, and include API error details when a real delivery attempt fails. Assisted-by: Codex:gpt-5.5
Pass the Lettermint API token, sender, and recipient secrets into the Node, Deno, and Bun test jobs so the Lettermint transport integration tests run when those secrets are configured. Assisted-by: Codex:gpt-5.5
10cb46c to
c1602ae
Compare
Remove the unsupported Lettermint validateSsl option instead of advertising a setting that standard fetch cannot honor portably. The HTTP client now relies on AbortSignal.any for combined request signals and removes retry backoff abort listeners when timers settle. #23 (comment) #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
Collect base64 output characters in an array and join once at the end. This avoids repeated intermediate string allocation for larger attachments while preserving the encoded output. #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding support for the Lettermint transactional email provider to the Upyo library. The implementation includes the LettermintTransport class, comprehensive configuration handling, and a message converter that supports single and batch sending, idempotency, and attachments. Feedback focuses on ensuring runtime compatibility by increasing the minimum Node.js version to 20.3.0 to support AbortSignal.any() and optimizing the Base64 encoding logic to improve performance when handling large attachments.
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding a new transport for the Lettermint HTTP API to the Upyo email library. The implementation supports single and batch sending, idempotency keys, attachments, and provider-specific settings such as routes and tracking. Feedback indicates a compatibility issue where AbortSignal.any() requires a higher Node.js version than the minimum specified in package.json. Additionally, it is recommended to improve error handling in batch sends to ensure that a single message conversion failure does not invalidate the entire batch or result in misleading error reports.
|
Codex Review: Didn't find any major issues. Another round soon, please! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Keep the Lettermint package compatible with its declared Node 20.0 runtime floor by using a cleanup-aware fallback when AbortSignal.any is not available. Batch conversion now reports per-message conversion errors instead of failing the whole chunk before valid messages are sent. #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, providing a new transport implementation for the Lettermint HTTP API. The implementation supports single and batch email sending, idempotency, attachments, and provider-specific features like routes and tracking settings. Documentation and extensive tests have also been added. Review feedback suggests improving the robustness of idempotency key handling by ensuring empty strings are treated as missing values and enhancing cross-runtime compatibility by using globalThis.crypto for UUID generation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e73db5d27a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Treat empty idempotency keys as missing so Lettermint requests always receive a usable generated key. Generate keys through globalThis.crypto when available, then fall back to the timestamp and random string path. #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
/gemini review |
|
@codex review |
Map Lettermint responses through a shared receipt helper so statuses that already indicate non-delivery produce failed receipts even when the API includes a message ID. This keeps single and batch sends from reporting suppressed, rejected, blocked, bounced, or failed messages as successful. #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding a new transport implementation for the Lettermint HTTP API. The implementation supports single and batch message sending, idempotency, and provider-specific features such as routes and tracking. Feedback focuses on enhancing the reliability and performance of the transport by adding jitter to the exponential backoff logic, including HTTP 408 errors in the retry mechanism, and utilizing native Base64 encoding instead of a manual implementation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3ff4dcd33a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding a new transport for the Lettermint transactional email service. The implementation includes a LettermintTransport class supporting single and batch sends, idempotency, and provider-specific features such as routes and tracking settings. Feedback recommends enhancing the retry logic with jitter to prevent thundering herd issues, optimizing base64 encoding for attachments using native Buffer methods, and simplifying the idempotency key generation by relying on the globally available Web Crypto API.
Add jitter to retry backoff and retry HTTP 408 responses so transient request timeouts follow the same recovery path as rate limits and server errors. Preserve caller cancellation as AbortError and keep local batch validation failures when the remote batch request fails. Attachment encoding now uses chunked native btoa, which avoids the manual base64 table while remaining portable across Deno, Node.js, Bun, and edge runtimes. Idempotency keys now rely directly on Web Crypto randomUUID. #23 (comment) #23 (comment) #23 (comment) #23 (comment) #23 (comment) #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, providing a new transport for the Lettermint email service. The implementation includes the LettermintTransport class, a dedicated HTTP client with exponential backoff retry logic, and a message converter to map Upyo messages to the Lettermint API format. Feedback focuses on ensuring unique idempotency keys when chunking batch requests to prevent unintended deduplication, optimizing the base64 conversion to avoid inefficient string concatenation in loops, and refining the retry logic to exclude non-transient status codes like 3xx redirections.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e24eb98e76
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Preserve per-message idempotency in sendMany by sending keyed chunks through the single-message endpoint, where each message can keep its own Idempotency-Key header. Unkeyed chunks still use Lettermint batch requests with generated request keys. Tighten retry classification so only transient HTTP statuses are retried, and avoid repeated string concatenation while building base64 attachment payloads. #23 (comment) #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
@codex review |
|
/gemini review |
|
Codex Review: Didn't find any major issues. Hooray! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding support for the Lettermint transactional email provider to the Upyo library. The implementation includes a LettermintTransport class, an HTTP client with retry logic and idempotency support, and a message converter that handles attachments and provider-specific features like routes and tags. Documentation and project-wide configurations have been updated to reflect the new transport. Feedback from the review suggests optimizing the base64 encoding of attachments by using the Buffer API and improving URL construction to handle potential trailing slashes in the base URL configuration.
Normalize configured Lettermint base URLs once while resolving config so single and batch send endpoints do not inherit trailing slash artifacts. Prefer native Uint8Array base64 encoding when the runtime provides it, while keeping the chunked btoa fallback for older runtimes. #23 (comment) #23 (comment) #23 (comment) Assisted-by: Codex:gpt-5.5
|
/gemini review |
|
@codex review |
There was a problem hiding this comment.
Code Review
This pull request introduces the @upyo/lettermint package, adding support for the Lettermint transactional email provider. The implementation includes a LettermintTransport class that supports single and batch sending (up to 500 messages), idempotency keys, attachments, and provider-specific features like routes, tags, and tracking settings. Comprehensive documentation and tests (unit and E2E) are also included. I have no feedback to provide as there are no review comments.
|
Codex Review: Didn't find any major issues. 🚀 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The CI Deno type definitions already include Uint8Array.toBase64(), so the previous type guard narrowed the fallback branch to never and failed the repository check. Use optional method lookup instead. This keeps the native path when a runtime supports it without making the chunked fallback unreachable to newer type libraries. https://github.com/dahlia/upyo/actions/runs/25988067832/job/76389109622 Assisted-by: Codex:gpt-5.5
Summary
This PR adds a new Lettermint transport package for Upyo, available as
@upyo/lettermint.The new package in packages/lettermint includes configuration helpers, message conversion, HTTP API delivery, idempotency keys, retry handling, timeout handling, and batch sending. It also includes cross-runtime unit tests and optional E2E tests guarded by Lettermint environment variables.
The implementation preserves Upyo attachment MIME types when converting to Lettermint’s
content_typefield, retries internal request timeouts according to the configured retry count, and streamssendMany()input in 500-message chunks instead of buffering the whole iterable before sending.Documentation
This also documents the transport in packages/lettermint/README.md and docs/transports/lettermint.md, adds it to the root package list in README.md, wires it into the VitePress navigation in docs/.vitepress/config.mts, and records the change in CHANGES.md.
Verification
deno task -c packages/lettermint/deno.json test-alldeno task checkcd docs && pnpm build