Skip to content

Commit

Permalink
Final touches before new major release (#25)
Browse files Browse the repository at this point in the history
* Final touches before new major release
  • Loading branch information
fpseverino authored Jan 29, 2025
1 parent e165ef0 commit 078282f
Show file tree
Hide file tree
Showing 16 changed files with 346 additions and 206 deletions.
3 changes: 1 addition & 2 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
version: 1
builder:
configs:
- documentation_targets: [SendGridKit]
swift_version: 6.0
- documentation_targets: [SendGridKit]
70 changes: 70 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"fileScopedDeclarationPrivacy": {
"accessLevel": "private"
},
"indentation": {
"spaces": 4
},
"indentConditionalCompilationBlocks": true,
"indentSwitchCaseLabels": false,
"lineBreakAroundMultilineExpressionChainComponents": false,
"lineBreakBeforeControlFlowKeywords": false,
"lineBreakBeforeEachArgument": false,
"lineBreakBeforeEachGenericRequirement": false,
"lineLength": 140,
"maximumBlankLines": 1,
"multiElementCollectionTrailingCommas": true,
"noAssignmentInExpressions": {
"allowedFunctions": [
"XCTAssertNoThrow"
]
},
"prioritizeKeepingFunctionOutputTogether": false,
"respectsExistingLineBreaks": true,
"rules": {
"AllPublicDeclarationsHaveDocumentation": false,
"AlwaysUseLiteralForEmptyCollectionInit": false,
"AlwaysUseLowerCamelCase": true,
"AmbiguousTrailingClosureOverload": true,
"BeginDocumentationCommentWithOneLineSummary": false,
"DoNotUseSemicolons": true,
"DontRepeatTypeInStaticProperties": true,
"FileScopedDeclarationPrivacy": true,
"FullyIndirectEnum": true,
"GroupNumericLiterals": true,
"IdentifiersMustBeASCII": true,
"NeverForceUnwrap": false,
"NeverUseForceTry": false,
"NeverUseImplicitlyUnwrappedOptionals": false,
"NoAccessLevelOnExtensionDeclaration": true,
"NoAssignmentInExpressions": true,
"NoBlockComments": true,
"NoCasesWithOnlyFallthrough": true,
"NoEmptyTrailingClosureParentheses": true,
"NoLabelsInCasePatterns": true,
"NoLeadingUnderscores": false,
"NoParensAroundConditions": true,
"NoPlaygroundLiterals": true,
"NoVoidReturnOnFunctionSignature": true,
"OmitExplicitReturns": false,
"OneCasePerLine": true,
"OneVariableDeclarationPerLine": true,
"OnlyOneTrailingClosureArgument": true,
"OrderedImports": true,
"ReplaceForEachWithForLoop": true,
"ReturnVoidInsteadOfEmptyTuple": true,
"TypeNamesShouldBeCapitalized": true,
"UseEarlyExits": false,
"UseExplicitNilCheckInConditions": true,
"UseLetInEveryBoundCaseVariable": true,
"UseShorthandTypeNames": true,
"UseSingleLinePropertyGetter": true,
"UseSynthesizedInitializer": true,
"UseTripleSlashForDocumentationComments": true,
"UseWhereClausesInForLoops": false,
"ValidateDocumentationComments": false
},
"spacesAroundRangeFormationOperators": false,
"tabWidth": 8,
"version": 1
}
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,32 @@
</div>
<br>

📧 SendGridKit is a Swift package used to communicate with the SendGrid API for Server Side Swift Apps.
📧 SendGridKit is a Swift package that helps you communicate with the SendGrid API in your Server Side Swift applications.

Send simple emails, or leverage the full capabilities of [SendGrid's V3 API](https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send).
Send simple emails or leverage the full capabilities of [SendGrid's V3 API](https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send).

### Getting Started

Use the SPM string to easily include the dependendency in your `Package.swift` file

```swift
.package(url: "https://github.com/vapor-community/sendgrid-kit.git", from: "3.0.0-rc.1")
.package(url: "https://github.com/vapor-community/sendgrid-kit.git", from: "3.0.0"),
```

and add it to your target's dependencies:

```swift
.product(name: "SendGridKit", package: "sendgrid-kit")
.product(name: "SendGridKit", package: "sendgrid-kit"),
```

## Overview

Register the config and the provider.

```swift
import AsyncHTTPClient
import SendGridKit

let httpClient = HTTPClient(...)
let sendGridClient = SendGridClient(httpClient: httpClient, apiKey: "YOUR_API_KEY")
```
Expand All @@ -65,6 +68,8 @@ If the request to the API failed for any reason a `SendGridError` is thrown, whi
Simply ensure you catch errors thrown like any other throwing function.

```swift
import SendGridKit

do {
try await sendGridClient.send(email: email)
} catch let error as SendGridError {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// An object allowing you to specify how to handle unsubscribes.
public struct AdvancedSuppressionManager: Codable, Sendable {
/// The unsubscribe group to associate with this email.
///
Expand Down
1 change: 1 addition & 0 deletions Sources/SendGridKit/Models/EmailAddress.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// An email address to use in an email to be sent via the SendGrid API.
public struct EmailAddress: Codable, Sendable {
/// The email address of the person to whom you are sending an email.
public var email: String
Expand Down
5 changes: 5 additions & 0 deletions Sources/SendGridKit/Models/EmailAttachment.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// An attachment to include in an email.
public struct EmailAttachment: Codable, Sendable {
/// The Base64 encoded content of the attachment.
public var content: String
Expand All @@ -19,8 +20,12 @@ public struct EmailAttachment: Codable, Sendable {
/// such as opening or downloading the file.
public var disposition: Disposition?

/// The disposition of the attachment.
public enum Disposition: String, Codable, Sendable {
/// The attachment is displayed automatically within the message.
case inline

/// The attached file requires some action to be taken before it is displayed.
case attachment
}

Expand Down
1 change: 1 addition & 0 deletions Sources/SendGridKit/Models/EmailContent.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// The content of an email.
public struct EmailContent: Codable, Sendable {
/// The MIME type of the content you are including in your email.
///
Expand Down
55 changes: 34 additions & 21 deletions Sources/SendGridKit/Models/MailSettings.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// Advanced settings to control how you would like to handle the email.
public struct MailSettings: Codable, Sendable {
/// Allows you to bypass all unsubscribe groups and suppressions to ensure that the email is delivered to every single recipient.
///
Expand Down Expand Up @@ -47,32 +48,44 @@ public struct MailSettings: Codable, Sendable {
}
}

public struct Setting: Codable, Sendable {
/// Indicates if this setting is enabled.
public var enable: Bool
extension MailSettings {
/// Indicates if a setting of ``MailSettings`` is enabled.
public struct Setting: Codable, Sendable, ExpressibleByBooleanLiteral {
/// Indicates if this setting is enabled.
public var enable: Bool

public init(enable: Bool) {
self.enable = enable
public init(enable: Bool) {
self.enable = enable
}

public init(booleanLiteral value: Bool) {
self.init(enable: value)
}
}
}

public struct Footer: Codable, Sendable {
/// Indicates if this setting is enabled.
public var enable: Bool
/// The default footer that you would like included on every email.
public struct Footer: Codable, Sendable, ExpressibleByBooleanLiteral {
/// Indicates if this setting is enabled.
public var enable: Bool

/// The plain text content of your footer.
public var text: String?

/// The plain text content of your footer.
public var text: String?
/// The HTML content of your footer.
public var html: String?

/// The HTML content of your footer.
public var html: String?
public init(
enable: Bool,
text: String? = nil,
html: String? = nil
) {
self.enable = enable
self.text = text
self.html = html
}

public init(
enable: Bool,
text: String? = nil,
html: String? = nil
) {
self.enable = enable
self.text = text
self.html = html
public init(booleanLiteral value: Bool) {
self.init(enable: value)
}
}
}
1 change: 1 addition & 0 deletions Sources/SendGridKit/Models/Personalization.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// An object containing the personalization of an email.
public struct Personalization<DynamicTemplateData: Codable & Sendable>: Codable, Sendable {
/// An array of recipients.
///
Expand Down
3 changes: 3 additions & 0 deletions Sources/SendGridKit/Models/SendGridEmail.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

/// An email to be sent using the SendGrid API.
public struct SendGridEmail<DynamicTemplateData: Codable & Sendable>: Codable, Sendable {
/// An array of messages and their metadata.
///
Expand Down Expand Up @@ -78,6 +79,7 @@ public struct SendGridEmail<DynamicTemplateData: Codable & Sendable>: Codable, S
/// Settings to determine how you would like to track the metrics of how your recipients interact with your email.
public var trackingSettings: TrackingSettings?

/// Initialize a new ``SendGridEmail`` using a custom dynamic template data type.
public init(
personalizations: [Personalization<DynamicTemplateData>],
from: EmailAddress,
Expand Down Expand Up @@ -138,6 +140,7 @@ public struct SendGridEmail<DynamicTemplateData: Codable & Sendable>: Codable, S
}

extension SendGridEmail where DynamicTemplateData == [String: String] {
/// Initialize a new ``SendGridEmail`` using a dictionary of `String` as dynamic template data.
public init(
personalizations: [Personalization<[String: String]>],
from: EmailAddress,
Expand Down
21 changes: 12 additions & 9 deletions Sources/SendGridKit/Models/SendGridError.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import Foundation

/// An error response from the SendGrid API.
public struct SendGridError: Error, Decodable, Sendable {
public var errors: [SendGridErrorResponse]?
/// The errors returned by the SendGrid API.
public var errors: [Description]?

/// When applicable, this property value will be an error ID.
public var id: String?
}

public struct SendGridErrorResponse: Decodable, Sendable {
/// An error message.
public var message: String?
/// The description of the ``SendGridError``.
public struct Description: Decodable, Sendable {
/// An error message.
public var message: String?

/// When applicable, this property value will be the field that generated the error.
public var field: String?
/// When applicable, this property value will be the field that generated the error.
public var field: String?

/// When applicable, this property value will be helper text or a link to documentation to help you troubleshoot the error.
public var help: String?
/// When applicable, this property value will be helper text or a link to documentation to help you troubleshoot the error.
public var help: String?
}
}
Loading

0 comments on commit 078282f

Please sign in to comment.