resend 0.27.0 → 1.6.0

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.
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resend
4
+ # Response wrapper that maintains backwards compatibility while exposing headers
5
+ #
6
+ # This class wraps API responses and behaves like a Hash for backwards compatibility,
7
+ # while also providing access to response headers via the #headers method.
8
+ #
9
+ # @example Backwards compatible hash access
10
+ # response = Resend::Emails.send(params)
11
+ # response[:id] # => "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"
12
+ #
13
+ # @example Accessing response headers
14
+ # response = Resend::Emails.send(params)
15
+ # response.headers # => {"content-type" => "application/json", ...}
16
+ # response.headers['x-ratelimit-remaining'] # => "50"
17
+ class Response
18
+ include Enumerable
19
+
20
+ # @param data [Hash] The response data
21
+ # @param headers [Hash, HTTParty::Response] The response headers
22
+ def initialize(data, headers)
23
+ @data = data.is_a?(Hash) ? data : {}
24
+ @headers = normalize_headers(headers)
25
+ end
26
+
27
+ # Access response headers
28
+ # @return [Hash] Response headers as a hash with lowercase string keys
29
+ attr_reader :headers
30
+
31
+ # Hash-like access via []
32
+ # @param key [Symbol, String] The key to access
33
+ # @return [Object] The value at the key
34
+ def [](key)
35
+ @data[key]
36
+ end
37
+
38
+ # Hash-like assignment via []=
39
+ # @param key [Symbol, String] The key to set
40
+ # @param value [Object] The value to set
41
+ def []=(key, value)
42
+ @data[key] = value
43
+ end
44
+
45
+ # Dig into nested hash structure
46
+ # @param keys [Array<Symbol, String>] Keys to dig through
47
+ # @return [Object] The value at the nested key path
48
+ def dig(*keys)
49
+ @data.dig(*keys)
50
+ end
51
+
52
+ # Convert to plain hash
53
+ # @return [Hash] The underlying data hash
54
+ def to_h
55
+ @data
56
+ end
57
+
58
+ alias to_hash to_h
59
+
60
+ # Get all keys from the data
61
+ # @return [Array] Array of keys
62
+ def keys
63
+ @data.keys
64
+ end
65
+
66
+ # Get all values from the data
67
+ # @return [Array] Array of values
68
+ def values
69
+ @data.values
70
+ end
71
+
72
+ # Check if key exists
73
+ # @param key [Symbol, String] The key to check
74
+ # @return [Boolean] True if key exists
75
+ def key?(key)
76
+ @data.key?(key)
77
+ end
78
+
79
+ alias has_key? key?
80
+
81
+ # Enable enumeration over the data
82
+ def each(&block)
83
+ @data.each(&block)
84
+ end
85
+
86
+ # Transform keys in the underlying data
87
+ # @return [Resend::Response] Self for chaining
88
+ def transform_keys!(&block)
89
+ @data.transform_keys!(&block)
90
+ self
91
+ end
92
+
93
+ # Check if response is empty
94
+ # @return [Boolean] True if data is empty
95
+ def empty?
96
+ @data.empty?
97
+ end
98
+
99
+ # Respond to hash-like methods
100
+ def respond_to_missing?(method_name, include_private = false)
101
+ @data.respond_to?(method_name) || super
102
+ end
103
+
104
+ # Delegate unknown methods to the underlying data hash
105
+ def method_missing(method_name, *args, &block)
106
+ if @data.respond_to?(method_name)
107
+ result = @data.send(method_name, *args, &block)
108
+ # If the method returns the hash itself, return self to maintain wrapper
109
+ result.equal?(@data) ? self : result
110
+ else
111
+ super
112
+ end
113
+ end
114
+
115
+ # String representation for debugging
116
+ # @return [String] String representation of the response
117
+ def inspect
118
+ "#<Resend::Response data=#{@data.inspect} headers=#{@headers.keys.inspect}>"
119
+ end
120
+
121
+ private
122
+
123
+ # Normalize headers to a simple hash with lowercase string keys
124
+ # @param headers [Hash, HTTParty::Response, nil] The headers to normalize
125
+ # @return [Hash] Normalized headers hash
126
+ def normalize_headers(headers)
127
+ return {} if headers.nil?
128
+
129
+ # Handle HTTParty::Response object
130
+ headers = headers.headers if headers.respond_to?(:headers)
131
+
132
+ # Convert to hash and normalize keys to lowercase strings
133
+ case headers
134
+ when Hash
135
+ headers.to_h.transform_keys { |k| k.to_s.downcase }
136
+ else
137
+ {}
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resend
4
+ # Segments api wrapper
5
+ module Segments
6
+ class << self
7
+ # https://resend.com/docs/api-reference/segments/create-segment
8
+ def create(params)
9
+ path = "segments"
10
+ Resend::Request.new(path, params, "post").perform
11
+ end
12
+
13
+ # https://resend.com/docs/api-reference/segments/get-segment
14
+ def get(segment_id = "")
15
+ path = "segments/#{segment_id}"
16
+ Resend::Request.new(path, {}, "get").perform
17
+ end
18
+
19
+ # https://resend.com/docs/api-reference/segments/list-segments
20
+ def list(params = {})
21
+ path = Resend::PaginationHelper.build_paginated_path("segments", params)
22
+ Resend::Request.new(path, {}, "get").perform
23
+ end
24
+
25
+ # https://resend.com/docs/api-reference/segments/delete-segment
26
+ def remove(segment_id = "")
27
+ path = "segments/#{segment_id}"
28
+ Resend::Request.new(path, {}, "delete").perform
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resend
4
+ # Templates api wrapper
5
+ module Templates
6
+ class << self
7
+ # https://resend.com/docs/api-reference/templates/create-template
8
+ def create(params = {})
9
+ path = "templates"
10
+ Resend::Request.new(path, params, "post").perform
11
+ end
12
+
13
+ # https://resend.com/docs/api-reference/templates/get-template
14
+ def get(template_id = "")
15
+ path = "templates/#{template_id}"
16
+ Resend::Request.new(path, {}, "get").perform
17
+ end
18
+
19
+ # https://resend.com/docs/api-reference/templates/update-template
20
+ def update(template_id, params = {})
21
+ path = "templates/#{template_id}"
22
+ Resend::Request.new(path, params, "patch").perform
23
+ end
24
+
25
+ # https://resend.com/docs/api-reference/templates/publish-template
26
+ def publish(template_id = "")
27
+ path = "templates/#{template_id}/publish"
28
+ Resend::Request.new(path, {}, "post").perform
29
+ end
30
+
31
+ # https://resend.com/docs/api-reference/templates/duplicate-template
32
+ def duplicate(template_id = "")
33
+ path = "templates/#{template_id}/duplicate"
34
+ Resend::Request.new(path, {}, "post").perform
35
+ end
36
+
37
+ # https://resend.com/docs/api-reference/templates/list-templates
38
+ def list(params = {})
39
+ path = Resend::PaginationHelper.build_paginated_path("templates", params)
40
+ Resend::Request.new(path, {}, "get").perform
41
+ end
42
+
43
+ # https://resend.com/docs/api-reference/templates/delete-template
44
+ def remove(template_id = "")
45
+ path = "templates/#{template_id}"
46
+ Resend::Request.new(path, {}, "delete").perform
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resend
4
+ # Topics api wrapper
5
+ module Topics
6
+ class << self
7
+ # https://resend.com/docs/api-reference/topics/create-topic
8
+ def create(params = {})
9
+ path = "topics"
10
+ Resend::Request.new(path, params, "post").perform
11
+ end
12
+
13
+ # https://resend.com/docs/api-reference/topics/get-topic
14
+ def get(topic_id = "")
15
+ path = "topics/#{topic_id}"
16
+ Resend::Request.new(path, {}, "get").perform
17
+ end
18
+
19
+ # https://resend.com/docs/api-reference/topics/update-topic
20
+ def update(params = {})
21
+ path = "topics/#{params[:topic_id]}"
22
+ Resend::Request.new(path, params, "patch").perform
23
+ end
24
+
25
+ # https://resend.com/docs/api-reference/topics/list-topics
26
+ def list(params = {})
27
+ path = Resend::PaginationHelper.build_paginated_path("topics", params)
28
+ Resend::Request.new(path, {}, "get").perform
29
+ end
30
+
31
+ # https://resend.com/docs/api-reference/topics/delete-topic
32
+ def remove(topic_id = "")
33
+ path = "topics/#{topic_id}"
34
+ Resend::Request.new(path, {}, "delete").perform
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Resend
4
- VERSION = "0.27.0"
4
+ VERSION = "1.6.0"
5
5
  end
data/lib/resend.rb CHANGED
@@ -8,19 +8,36 @@ require "httparty"
8
8
  require "json"
9
9
  require "cgi"
10
10
  require "resend/errors"
11
+ require "resend/response"
11
12
  require "resend/client"
12
13
  require "resend/request"
14
+ require "resend/multipart_request"
13
15
  require "resend/pagination_helper"
14
16
 
15
17
  # API Operations
16
- require "resend/audiences"
18
+ require "resend/segments"
17
19
  require "resend/api_keys"
18
20
  require "resend/broadcasts"
19
21
  require "resend/batch"
20
22
  require "resend/contacts"
23
+ require "resend/contacts/imports"
24
+ require "resend/contacts/segments"
25
+ require "resend/contacts/topics"
26
+ require "resend/contact_properties"
21
27
  require "resend/domains"
28
+ require "resend/domains/claims"
22
29
  require "resend/emails"
30
+ require "resend/templates"
31
+ require "resend/emails/receiving"
32
+ require "resend/emails/attachments"
33
+ require "resend/emails/receiving/attachments"
34
+ require "resend/logs"
35
+ require "resend/topics"
23
36
  require "resend/webhooks"
37
+ require "resend/oauth_grants"
38
+ require "resend/automations"
39
+ require "resend/automations/runs"
40
+ require "resend/events"
24
41
 
25
42
  # Rails
26
43
  require "resend/railtie" if defined?(Rails) && defined?(ActionMailer)
@@ -36,4 +53,7 @@ module Resend
36
53
  end
37
54
  alias config configure
38
55
  end
56
+
57
+ # @deprecated Use Segments instead
58
+ Audiences = Segments
39
59
  end
metadata CHANGED
@@ -1,71 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derich Pacheco
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-10-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: httparty
13
+ name: base64
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 0.21.0
18
+ version: '0'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 0.21.0
25
+ version: '0'
27
26
  - !ruby/object:Gem::Dependency
28
- name: rails
27
+ name: httparty
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
32
+ version: 0.22.0
33
+ type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
41
- description:
39
+ version: 0.22.0
42
40
  email: carlosderich@gmail.com
43
41
  executables: []
44
42
  extensions: []
45
43
  extra_rdoc_files: []
46
44
  files:
45
+ - CHANGELOG.md
47
46
  - README.md
48
47
  - lib/resend.rb
49
48
  - lib/resend/api_keys.rb
50
- - lib/resend/audiences.rb
49
+ - lib/resend/automations.rb
50
+ - lib/resend/automations/runs.rb
51
51
  - lib/resend/batch.rb
52
52
  - lib/resend/broadcasts.rb
53
53
  - lib/resend/client.rb
54
+ - lib/resend/contact_properties.rb
54
55
  - lib/resend/contacts.rb
56
+ - lib/resend/contacts/imports.rb
57
+ - lib/resend/contacts/segments.rb
58
+ - lib/resend/contacts/topics.rb
55
59
  - lib/resend/domains.rb
60
+ - lib/resend/domains/claims.rb
56
61
  - lib/resend/emails.rb
62
+ - lib/resend/emails/attachments.rb
63
+ - lib/resend/emails/receiving.rb
64
+ - lib/resend/emails/receiving/attachments.rb
57
65
  - lib/resend/errors.rb
66
+ - lib/resend/events.rb
67
+ - lib/resend/logs.rb
58
68
  - lib/resend/mailer.rb
69
+ - lib/resend/multipart_request.rb
70
+ - lib/resend/oauth_grants.rb
59
71
  - lib/resend/pagination_helper.rb
60
72
  - lib/resend/railtie.rb
61
73
  - lib/resend/request.rb
74
+ - lib/resend/response.rb
75
+ - lib/resend/segments.rb
76
+ - lib/resend/templates.rb
77
+ - lib/resend/topics.rb
62
78
  - lib/resend/version.rb
63
79
  - lib/resend/webhooks.rb
64
80
  homepage: https://github.com/resend/resend-ruby
65
81
  licenses:
66
82
  - MIT
67
83
  metadata: {}
68
- post_install_message:
69
84
  rdoc_options: []
70
85
  require_paths:
71
86
  - lib
@@ -73,15 +88,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
88
  requirements:
74
89
  - - ">="
75
90
  - !ruby/object:Gem::Version
76
- version: '2.6'
91
+ version: '3.2'
77
92
  required_rubygems_version: !ruby/object:Gem::Requirement
78
93
  requirements:
79
94
  - - ">="
80
95
  - !ruby/object:Gem::Version
81
96
  version: '0'
82
97
  requirements: []
83
- rubygems_version: 3.4.10
84
- signing_key:
98
+ rubygems_version: 3.6.9
85
99
  specification_version: 4
86
100
  summary: The Ruby and Rails SDK for resend.com
87
101
  test_files: []
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Resend
4
- # Audiences api wrapper
5
- module Audiences
6
- class << self
7
- # https://resend.com/docs/api-reference/audiences/create-audience
8
- def create(params)
9
- path = "audiences"
10
- Resend::Request.new(path, params, "post").perform
11
- end
12
-
13
- # https://resend.com/docs/api-reference/audiences/get-audience
14
- def get(audience_id = "")
15
- path = "audiences/#{audience_id}"
16
- Resend::Request.new(path, {}, "get").perform
17
- end
18
-
19
- # https://resend.com/docs/api-reference/audiences/list-audiences
20
- def list(params = {})
21
- path = Resend::PaginationHelper.build_paginated_path("audiences", params)
22
- Resend::Request.new(path, {}, "get").perform
23
- end
24
-
25
- # https://resend.com/docs/api-reference/audiences/delete-audience
26
- def remove(audience_id = "")
27
- path = "audiences/#{audience_id}"
28
- Resend::Request.new(path, {}, "delete").perform
29
- end
30
- end
31
- end
32
- end