smbcloud-email 1.0.0-arm64-darwin

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 12dd58b8903f8401c07be0e6b1bcd00c39dd63cbd448f761da1d39adeebc4231
4
+ data.tar.gz: '08872fc1a3ed1b02687a8b0299f3e8836a254f43261bca4f25e3eb75cc53c5f5'
5
+ SHA512:
6
+ metadata.gz: db637789655fdbad9d4b841d0045e2952e0f83bef27e13794f623efff6f545b98c856576c11c6137b537ed1af130fc88292296238e8eea0894ff2141792b2f6e
7
+ data.tar.gz: d82b2a473f766d6309ad39f0983849a1ce46492fb3fbdd5c9a5f4a48994d1214e87584411be6198cfd095f877b17d0250b78402f5c6e5e148a30baf8f4758813
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [0.4.7] - 2026-06-30
4
+
5
+ - Initial release. Ruby bindings for the smbCloud transactional email API:
6
+ `SmbCloud::Email::Client#send`, `#get_message`, and `#list_messages`,
7
+ powered by the shared Rust SDK (`smbcloud-email-sdk`) via a native Magnus
8
+ extension.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # smbcloud-email (Ruby)
2
+
3
+ Ruby bindings for the **smbCloud transactional email API**, powered by the shared
4
+ Rust SDK ([`smbcloud-email-sdk`](../../../crates/smbcloud-email-sdk)) and a native
5
+ [Magnus](https://github.com/matsadler/magnus) extension.
6
+
7
+ ## Install
8
+
9
+ ```ruby
10
+ gem 'smbcloud-email'
11
+ ```
12
+
13
+ The gem ships a native extension; `bundle install` compiles it (Rust toolchain
14
+ required).
15
+
16
+ ## Usage
17
+
18
+ ```ruby
19
+ require 'email'
20
+
21
+ client = SmbCloud::Email.client(
22
+ environment: SmbCloud::Email::Environment::PRODUCTION,
23
+ api_key: 'smb_mail_your_key',
24
+ )
25
+
26
+ # Send
27
+ sent = client.send(
28
+ from: 'billing@example.com',
29
+ to: ['customer@acme.com'],
30
+ subject: 'Your receipt',
31
+ html: '<h1>Thanks!</h1>',
32
+ text: 'Thanks!',
33
+ idempotency_key: 'receipt-2026-0001',
34
+ )
35
+ sent[:id] # => "eml_…"
36
+ sent[:status] # => 1 (sent)
37
+
38
+ # Attachments, cc/bcc, headers, tags
39
+ client.send(
40
+ from: 'billing@example.com',
41
+ to: ['customer@acme.com'],
42
+ subject: 'Invoice',
43
+ html: '<p>See attached.</p>',
44
+ cc: ['accounts@acme.com'],
45
+ attachments: [{ filename: 'invoice.pdf', content_base64: 'JVBERi0xLjQ...' }],
46
+ headers: { 'X-Entity-Ref-ID' => 'inv_123' },
47
+ tags: { 'category' => 'invoice' },
48
+ )
49
+
50
+ # Delivery status (needs a read-scope key)
51
+ message = client.get_message('eml_…')
52
+ message[:status]
53
+ message[:events]
54
+
55
+ client.list_messages(status: 'bounced', limit: 20)
56
+ ```
57
+
58
+ Mint an API key for your Mail app in the smbCloud console. Sending is scoped to
59
+ that app's verified domain; reading messages needs a read-scope key.
60
+
61
+ ## Errors
62
+
63
+ Non-2xx API responses and transport failures raise `SmbCloud::Email::Error`, with
64
+ the parsed response body available on `#payload`.
65
+
66
+ ## License
67
+
68
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rb_sys/extensiontask'
5
+
6
+ task build: :compile
7
+
8
+ GEMSPEC = Gem::Specification.load('email.gemspec')
9
+
10
+ RbSys::ExtensionTask.new('email', GEMSPEC) do |ext|
11
+ ext.lib_dir = 'lib/email'
12
+ ext.cross_compile = true
13
+ ext.cross_platform = %w[x86_64-linux aarch64-linux arm64-darwin x86_64-darwin]
14
+ end
15
+
16
+ task default: :compile
data/ext/.keep ADDED
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Email
4
+ VERSION = '1.0.0'
5
+ end
data/lib/email.rb ADDED
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'email/version'
5
+ # Fat native gems ship one extension per Ruby minor (lib/email/3.4/email.bundle);
6
+ # source and single-ABI builds put it directly under lib/email/.
7
+ begin
8
+ RUBY_VERSION =~ /(\d+\.\d+)/
9
+ require_relative "email/#{Regexp.last_match(1)}/email"
10
+ rescue LoadError
11
+ require_relative 'email/email'
12
+ end
13
+
14
+ module Email
15
+ end
16
+
17
+ module SmbCloud
18
+ # Ruby bindings for the smbCloud transactional email API, powered by the shared
19
+ # Rust SDK (smbcloud-email-sdk) and a native Magnus extension.
20
+ #
21
+ # @example
22
+ # client = SmbCloud::Email.client(environment: "production", api_key: "smb_mail_…")
23
+ # sent = client.send(
24
+ # from: "billing@example.com",
25
+ # to: ["customer@acme.com"],
26
+ # subject: "Your receipt",
27
+ # html: "<h1>Thanks!</h1>",
28
+ # idempotency_key: "receipt-2026-0001",
29
+ # )
30
+ # sent[:id] # => "eml_…"
31
+ module Email
32
+ class Error < StandardError
33
+ attr_reader :payload
34
+
35
+ def initialize(message = nil, payload: nil)
36
+ super(message)
37
+ @payload = payload
38
+ end
39
+ end
40
+
41
+ module Environment
42
+ DEV = 'dev'
43
+ PRODUCTION = 'production'
44
+ end
45
+
46
+ class Client
47
+ attr_reader :environment, :api_key
48
+
49
+ def initialize(environment:, api_key:)
50
+ @environment = environment
51
+ @api_key = api_key
52
+ end
53
+
54
+ # Send a transactional email. `from` must be on the API key's verified
55
+ # domain; provide at least one of `html`/`text`. `attachments` is an array
56
+ # of { filename:, content_base64: }. Returns the created message hash.
57
+ def send(from:, to:, subject: nil, html: nil, text: nil, cc: nil, bcc: nil,
58
+ reply_to: nil, attachments: nil, headers: nil, tags: nil,
59
+ idempotency_key: nil)
60
+ message = {
61
+ from: from,
62
+ to: Array(to),
63
+ cc: Array(cc),
64
+ bcc: Array(bcc),
65
+ reply_to: Array(reply_to),
66
+ subject: subject,
67
+ html: html,
68
+ text: text,
69
+ attachments: Array(attachments),
70
+ headers: headers || {},
71
+ tags: tags || {},
72
+ idempotency_key: idempotency_key
73
+ }.compact
74
+
75
+ Email.send(:parse_json, Email.__send(environment, api_key, JSON.generate(message)))
76
+ rescue RuntimeError => e
77
+ raise Email.send(:normalize_error, e)
78
+ end
79
+
80
+ # Fetch one message by id, including its delivery-event timeline. Requires
81
+ # a read-scope key.
82
+ def get_message(id)
83
+ Email.send(:parse_json, Email.__get_message(environment, api_key, id))
84
+ rescue RuntimeError => e
85
+ raise Email.send(:normalize_error, e)
86
+ end
87
+
88
+ # List recent messages. `status` filters by delivery status name; `limit`
89
+ # is clamped server-side to 1..=100. Requires a read-scope key.
90
+ def list_messages(status: nil, limit: nil)
91
+ Email.send(:parse_json,
92
+ Email.__list_messages(environment, api_key, status.to_s, limit.to_i))
93
+ rescue RuntimeError => e
94
+ raise Email.send(:normalize_error, e)
95
+ end
96
+ end
97
+
98
+ class << self
99
+ def client(environment:, api_key:)
100
+ Client.new(environment:, api_key:)
101
+ end
102
+
103
+ def send_with_client(environment:, api_key:, **kwargs)
104
+ client(environment:, api_key:).send(**kwargs)
105
+ end
106
+
107
+ def get_message_with_client(environment:, api_key:, id:)
108
+ client(environment:, api_key:).get_message(id)
109
+ end
110
+
111
+ def list_messages_with_client(environment:, api_key:, status: nil, limit: nil)
112
+ client(environment:, api_key:).list_messages(status:, limit:)
113
+ end
114
+
115
+ private
116
+
117
+ def parse_json(payload)
118
+ return payload unless payload.is_a?(String)
119
+
120
+ JSON.parse(payload, symbolize_names: true)
121
+ end
122
+
123
+ def normalize_error(error)
124
+ payload = parse_json(error.message)
125
+ message = payload.is_a?(Hash) ? (payload[:message] || error.message) : error.message
126
+ Error.new(message, payload: payload)
127
+ rescue JSON::ParserError, NoMethodError, TypeError
128
+ Error.new(error.message)
129
+ end
130
+ end
131
+ end
132
+ end
data/sig/email.rbs ADDED
@@ -0,0 +1,28 @@
1
+ module Email
2
+ VERSION: String
3
+ end
4
+
5
+ module SmbCloud
6
+ module Email
7
+ class Error < StandardError
8
+ attr_reader payload: untyped
9
+ end
10
+
11
+ module Environment
12
+ DEV: String
13
+ PRODUCTION: String
14
+ end
15
+
16
+ class Client
17
+ attr_reader environment: String
18
+ attr_reader api_key: String
19
+
20
+ def initialize: (environment: String, api_key: String) -> void
21
+ def send: (from: String, to: untyped, ?subject: String?, ?html: String?, ?text: String?, ?cc: untyped, ?bcc: untyped, ?reply_to: untyped, ?attachments: untyped, ?headers: untyped, ?tags: untyped, ?idempotency_key: String?) -> Hash[Symbol, untyped]
22
+ def get_message: (String) -> Hash[Symbol, untyped]
23
+ def list_messages: (?status: String?, ?limit: Integer?) -> Array[Hash[Symbol, untyped]]
24
+ end
25
+
26
+ def self.client: (environment: String, api_key: String) -> Client
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smbcloud-email
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: arm64-darwin
6
+ authors:
7
+ - Seto Elkahfi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Send transactional email from a verified domain and read delivery status,
28
+ powered by the shared Rust SDK and a native Magnus extension.
29
+ email:
30
+ - seto@smbcloud.xyz
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - CHANGELOG.md
36
+ - README.md
37
+ - Rakefile
38
+ - ext/.keep
39
+ - lib/email.rb
40
+ - lib/email/3.1/email.bundle
41
+ - lib/email/3.2/email.bundle
42
+ - lib/email/3.3/email.bundle
43
+ - lib/email/3.4/email.bundle
44
+ - lib/email/4.0/email.bundle
45
+ - lib/email/version.rb
46
+ - sig/email.rbs
47
+ homepage: https://github.com/smbcloudXYZ/smbcloud-cli/tree/main/sdk/gems/email
48
+ licenses:
49
+ - MIT
50
+ metadata:
51
+ allowed_push_host: https://rubygems.org
52
+ homepage_uri: https://github.com/smbcloudXYZ/smbcloud-cli/tree/main/sdk/gems/email
53
+ source_code_uri: https://github.com/smbcloudXYZ/smbcloud-cli/tree/main/sdk/gems/email
54
+ changelog_uri: https://github.com/smbcloudXYZ/smbcloud-cli/tree/main/sdk/gems/email/CHANGELOG.md
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '3.1'
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: 4.1.dev
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 3.3.11
72
+ requirements: []
73
+ rubygems_version: 3.5.23
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Ruby bindings for the smbCloud transactional email API.
77
+ test_files: []