Skip to content

Commit 2803e22

Browse files
committed
Initial public release
0 parents  commit 2803e22

35 files changed

+1501
-0
lines changed

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
macos:
11+
runs-on: macos-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Set up Swift version
15+
uses: swift-actions/setup-swift@v2
16+
with:
17+
swift-version: '6.1.0'
18+
- name: Build
19+
run: swift build -v
20+
- name: Run tests
21+
run: swift test -v --no-parallel

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

.swiftpm/MailjetKit.xctestplan

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"configurations" : [
3+
{
4+
"id" : "EA73CEEA-BBDE-4751-B504-CBA56EC43228",
5+
"name" : "Test Scheme Action",
6+
"options" : {
7+
8+
}
9+
}
10+
],
11+
"defaultOptions" : {
12+
"performanceAntipatternCheckerEnabled" : true
13+
},
14+
"testTargets" : [
15+
{
16+
"parallelizable" : false,
17+
"target" : {
18+
"containerPath" : "container:",
19+
"identifier" : "MailjetKitTests",
20+
"name" : "MailjetKitTests"
21+
}
22+
}
23+
],
24+
"version" : 1
25+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "2600"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES"
8+
buildArchitectures = "Automatic">
9+
<BuildActionEntries>
10+
<BuildActionEntry
11+
buildForTesting = "YES"
12+
buildForRunning = "YES"
13+
buildForProfiling = "YES"
14+
buildForArchiving = "YES"
15+
buildForAnalyzing = "YES">
16+
<BuildableReference
17+
BuildableIdentifier = "primary"
18+
BlueprintIdentifier = "MailjetKit"
19+
BuildableName = "MailjetKit"
20+
BlueprintName = "MailjetKit"
21+
ReferencedContainer = "container:">
22+
</BuildableReference>
23+
</BuildActionEntry>
24+
</BuildActionEntries>
25+
</BuildAction>
26+
<TestAction
27+
buildConfiguration = "Debug"
28+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
29+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
30+
shouldUseLaunchSchemeArgsEnv = "YES">
31+
<TestPlans>
32+
<TestPlanReference
33+
reference = "container:.swiftpm/MailjetKit.xctestplan"
34+
default = "YES">
35+
</TestPlanReference>
36+
</TestPlans>
37+
<Testables>
38+
<TestableReference
39+
skipped = "NO"
40+
parallelizable = "NO">
41+
<BuildableReference
42+
BuildableIdentifier = "primary"
43+
BlueprintIdentifier = "MailjetKitTests"
44+
BuildableName = "MailjetKitTests"
45+
BlueprintName = "MailjetKitTests"
46+
ReferencedContainer = "container:">
47+
</BuildableReference>
48+
</TestableReference>
49+
</Testables>
50+
</TestAction>
51+
<LaunchAction
52+
buildConfiguration = "Debug"
53+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
54+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
55+
launchStyle = "0"
56+
useCustomWorkingDirectory = "NO"
57+
ignoresPersistentStateOnLaunch = "NO"
58+
debugDocumentVersioning = "YES"
59+
debugServiceExtension = "internal"
60+
allowLocationSimulation = "YES">
61+
</LaunchAction>
62+
<ProfileAction
63+
buildConfiguration = "Release"
64+
shouldUseLaunchSchemeArgsEnv = "YES"
65+
savedToolIdentifier = ""
66+
useCustomWorkingDirectory = "NO"
67+
debugDocumentVersioning = "YES">
68+
<MacroExpansion>
69+
<BuildableReference
70+
BuildableIdentifier = "primary"
71+
BlueprintIdentifier = "MailjetKit"
72+
BuildableName = "MailjetKit"
73+
BlueprintName = "MailjetKit"
74+
ReferencedContainer = "container:">
75+
</BuildableReference>
76+
</MacroExpansion>
77+
</ProfileAction>
78+
<AnalyzeAction
79+
buildConfiguration = "Debug">
80+
</AnalyzeAction>
81+
<ArchiveAction
82+
buildConfiguration = "Release"
83+
revealArchiveInOrganizer = "YES">
84+
</ArchiveAction>
85+
</Scheme>

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Adam Borbas
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.resolved

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// swift-tools-version: 6.1
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "MailjetKit",
6+
platforms: [
7+
.iOS(.v16), .macOS(.v10_15), .tvOS(.v13), .watchOS(.v6)
8+
],
9+
products: [
10+
.library(name: "MailjetKit", targets: ["MailjetKit"])
11+
],
12+
dependencies: [
13+
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.10.2")),
14+
.package(url: "https://github.com/WeTransfer/Mocker.git", .upToNextMajor(from: "3.0.0")),
15+
],
16+
targets: [
17+
.target(
18+
name: "MailjetKit",
19+
dependencies: [
20+
.product(name: "Alamofire", package: "Alamofire"),
21+
],
22+
path: "Sources"
23+
),
24+
.testTarget(
25+
name: "MailjetKitTests",
26+
dependencies: ["MailjetKit", "Mocker"],
27+
path: "Tests",
28+
resources: [ .copy("Resources")],
29+
)
30+
]
31+
)

README.MD

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# MailjetKit
2+
3+
A Swift package for sending emails through the [Mailjet API](https://dev.mailjet.com/email/guides/send-api-V3-1/).
4+
Currently supports the `/send` endpoint (v3.1).
5+
6+
## Overview
7+
8+
**MailjetKit** is a lightweight, type-safe Swift SDK for sending emails using Mailjet’s REST API.
9+
It focuses on simplicity, correctness, and modern Swift features such as:
10+
11+
- `async/await`
12+
- `Codable`-based request/response models
13+
- Strong typing for messages, recipients, and attachments
14+
- Fluent, immutable “with/adding” helpers for constructing messages
15+
16+
This package is ideal for server-side Swift (e.g. Vapor, Hummingbird, SwiftNIO apps), command-line tools, or macOS/iOS utilities that need to send transactional or templated emails.
17+
18+
## Features
19+
20+
- Fully asynchronous (using Swift Concurrency)
21+
- Type-safe Mailjet `/send` v3.1 endpoint
22+
- Strongly typed `Message`, `Envelope`, `Content`, and `Attachment` models
23+
- Immutable builder-style API (`addAttachment`, `addTo`, `addHeader`, etc.)
24+
25+
## Installation
26+
27+
### Swift Package Manager
28+
29+
Add **MailjetKit** to your `Package.swift` dependencies:
30+
31+
```swift
32+
dependencies: [
33+
.package(url: "https://github.com/adborbas/MailjetKit.git", from: "0.1.0")
34+
]
35+
```
36+
37+
Then add `"MailjetKit"` as a dependency to your target:
38+
39+
```swift
40+
.target(
41+
name: "MyApp",
42+
dependencies: [
43+
.product(name: "MailjetKit", package: "MailjetKit")
44+
]
45+
)
46+
```
47+
48+
## Usage and Examples
49+
50+
💡 Before using MailjetKit, you’ll need a Mailjet account and API credentials.
51+
You can [sign up for a Mailjet account](https://app.mailjet.com/signup) and then [create an API key](https://app.mailjet.com/account/apikeys) from your account dashboard.
52+
53+
### Create a Mailjet client
54+
55+
```swift
56+
import MailjetKit
57+
58+
let mailjet = MailjetKit(
59+
apiKey: "YOUR_API_KEY",
60+
apiSecret: "YOUR_API_SECRET"
61+
)
62+
```
63+
64+
### Send a simple email
65+
66+
```swift
67+
let message = Message(
68+
from: Recipient(email: "[email protected]", name: "Your App"),
69+
to: Recipient(email: "[email protected]", name: "Test User"),
70+
subject: "Welcome to MailjetKit!",
71+
textPart: "Hello there! This is a plain text email from MailjetKit."
72+
)
73+
74+
do {
75+
let response = try await mailjet.send(message: message)
76+
print("Message sent: \(response.status)")
77+
} catch {
78+
print("Error sending email: \(error)")
79+
}
80+
```
81+
82+
### Send an HTML email with attachments
83+
84+
```swift
85+
let htmlMessage = Message(
86+
from: Recipient(email: "[email protected]"),
87+
to: Recipient(email: "[email protected]"),
88+
subject: "Hello, HTML!",
89+
htmlPart: "<h1>Hello</h1><p>This is an <strong>HTML</strong> message.</p>"
90+
)
91+
.addAttachment(
92+
Attachment(
93+
contentType: "text/plain",
94+
filename: "example.txt",
95+
base64Content: Data("Hello world!".utf8).base64EncodedString()
96+
)
97+
)
98+
99+
do {
100+
let response = try await mailjet.send(message: htmlMessage)
101+
print("✅ Sent successfully: \(response)")
102+
} catch {
103+
print("❌ Failed: \(error)")
104+
}
105+
```
106+
107+
### Using a templated email
108+
109+
```swift
110+
let templatedMessage = Message(
111+
envelope: Envelope(
112+
from: Recipient(email: "[email protected]"),
113+
to: [Recipient(email: "[email protected]")]
114+
),
115+
template: TemplateOptions(
116+
templateID: 123456,
117+
templateLanguage: true,
118+
variables: [
119+
"name": "Jane Doe",
120+
"product": "MailjetKit"
121+
]
122+
)
123+
)
124+
125+
try await mailjet.send(message: templatedMessage)
126+
```

0 commit comments

Comments
 (0)