Skip to content

Migration: paginated sequence, webhooks, logging, docc, swiftlint, and comprehensive tests#2

Merged
asielcabrera merged 16 commits into
mainfrom
migration/ios-macos-linux
May 30, 2026
Merged

Migration: paginated sequence, webhooks, logging, docc, swiftlint, and comprehensive tests#2
asielcabrera merged 16 commits into
mainfrom
migration/ios-macos-linux

Conversation

@asielcabrera
Copy link
Copy Markdown
Collaborator

Summary

Complete overhaul of the Resend Swift SDK with cross-platform support, comprehensive testing, and documentation.

Changes

Features

  • PaginatedSequence: Cursor-based pagination with AsyncSequence conformance for all list endpoints
  • WebhookClient: Full create/get/list/listAll/update/delete webhook CRUD
  • WebhookSignature: Svix-compatible HMAC-SHA256 signature verification with replay protection
  • LoggingHTTPClient: swift-log integration with request/response logging
  • RetryHTTPClient: Exponential backoff with jitter, configurable via RetryConfiguration

Infrastructure

  • SwiftLint configuration with pre-commit hook and CI integration
  • swift-docc-plugin for documentation generation
  • visionOS platform support
  • Cross-platform compatibility (Linux, iOS, macOS, tvOS, watchOS, visionOS)

Code Quality

  • Fixed PaginatedSequence bug where isDone caused early nil return before draining queued items
  • Fixed keyDecodingStrategy = .convertFromSnakeCase conflict with custom CodingKeys
  • Added Sendable conformance to HTTPClientProtocol
  • Removed unused @unchecked Sendable from LoggingHTTPClient

Documentation

  • DocC inline documentation on all 46 public types across 4 modules
  • ResendCore.docc, ResendKit.docc, ResendVapor.docc catalogs
  • Full README rewrite with all features, examples, and API coverage

Testing

  • 178 tests across 33 suites (up from 109 in 18 suites)
  • Parameterized tests with Swift Testing @Test(arguments:)
  • Edge cases: empty/nil fields, extreme values, encode/decode roundtrips, JSON with extra keys
  • Retry tests for 502/503/504 status codes and all retryable URLError variants
  • Webhook signature edge cases: future timestamps, empty payloads, invalid secrets

- Fix parameter typo: createAt -> createdAt in ResendEmail
- Rename EmailAttachment.path to disposition (maps to 'path' JSON key)
- Remove unused Name struct from ResendClient
- Remove redundant CodingKeys in ResendRetrieveError
- Add MIT LICENSE file
- Add visionOS support to Package.swift
- Replace @_exported import with public import (stable Swift 5.9+)
- Add GitHub Actions CI workflows (macOS, Linux, iOS, visionOS)
- Add DocC documentation deployment workflow
…lients

- Add executeAndDecode(_:decoder:) extension on HTTPClientProtocol
- Eliminates 7-line error handling boilerplate from every client method
- Reduces EmailClient from 149 to 52 lines
- Reduces DomainClient from 200 to 68 lines
- Reduces APIKeyClient from 109 to 42 lines
- Reduces AudienceClient from 133 to 46 lines
- Reduces ContactClient from 180 to 63 lines
- Reduces BroadcastClient from 231 to 83 lines
…lete

- Change ResendBroadcast.replyTo from String? to [String]? to match API
- Change APIKeyClientProtocol.delete to return ResendDeleteResponse (was Void)
- Fix test data for API key delete endpoint
- Replace all JSONSerialization usage with typed Encodable request models
- Add CreateDomainRequest, UpdateDomainRequest
- Add CreateAPIKeyRequest
- Add CreateAudienceRequest
- Add CreateContactRequest, UpdateContactRequest
- Add CreateBroadcastRequest, UpdateBroadcastRequest, SendBroadcastRequest
- Add UpdateEmailRequest
- Type-safe request construction instead of dictionary-based payloads
- Add query parameter support to buildRequest() using URLQueryItem
- Replace manual string building for list queries in all clients
- Properly encodes special characters in query values
- Safer and more maintainable than string concatenation
- Add RetryConfiguration struct with customizable parameters
- Add RetryHTTPClient decorator implementing HTTPClientProtocol
- Retry on 429, 502, 503, 504 status codes and network errors
- Exponential backoff with optional jitter and Retry-After support
- Add retry parameter to ResendClient initializer
- Refactor MockHTTPClient to support interleaved errors and responses
…nd request logging

- Add PaginatedSequence for cursor-based pagination with AsyncSequence conformance
- Add WebhookClient with full create/get/list/listAll/update/delete API
- Add WebhookSignature with Svix-compatible HMAC-SHA256 verification
- Add LoggingHTTPClient decorator for swift-log integration
- Add retry and logger parameters to ResendClient initializer
- Add WebhookClientProtocol to ResendClientProtocol
- Update Package.swift with swift-crypto and visionOS support
- Add .swiftlint.yml with tuned rules (line_length: 340, disabled unused_parameter)
- Add .githooks/pre-commit that lints staged Swift files with --strict
- Add lint step to CI workflow running swiftlint lint --strict
- Add inline DocC documentation comments to all 46 public types across 4 modules
- Update ResendCore.docc with WebhookClientProtocol and PaginatedSequence
- Update ResendKit.docc with WebhookSignature, RetryHTTPClient, RetryConfiguration
- Create ResendVapor.docc for Vapor integration documentation
- Update root Documentation.docc with module overviews
- Rewrite README.md with complete API coverage, examples, and feature docs
…ed tests

- Fix PaginatedSequence.Iterator.next() draining remaining queued items
  before returning nil when isDone is true
- Add ParameterizedModelTests (178 test cases) covering EmailAttachment,
  EmailTag, ResendBroadcast, ResendContact, ResendWebhook, ResendAPIKey,
  ResendAudience, DNSRecord, ResendEmailResponse, ResendRetrieveError
- Add parameterized retry tests for 502/503/504 and URLError variants
- Add webhook signature edge cases (future timestamp, empty payload,
  invalid secret, trailing spaces, all-invalid signatures)
- Add pagination edge cases (error propagation, cursor tracking, 4-per-page)
… Sendable

- HTTPClientProtocol now requires Sendable conformance
- LoggingHTTPClient only needed @unchecked due to HTTPClientProtocol
- PaginatedSequence and Vapor Storage remain @unchecked (legitimate uses)
- Add Xcode user state, workspace, and scheme artifacts
- Add macOS system files (Icon?, .AppleDouble, etc.)
- Add IDE directories (.idea, .vscode, .vs)
- Add DocC build output, env files, logs, and generated files
- Remove Package.resolved (should be tracked)
…inux

# Conflicts:
#	Tests/ResendTests/ResendTests.swift
@asielcabrera asielcabrera merged commit adc66b0 into main May 30, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant