patch_retention 0.3.1 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9642c7116bc29f3cc1e9368c861ac11d13b2357ab778b4f9395fa2bb14c3edb3
4
- data.tar.gz: 7dc040049c15f9b32eb83d06a986daa0da1c4c881d1dfd2553dc764d9fbba494
3
+ metadata.gz: a4e08ff07a6967ecf42cb39dc2996ac46076344f46ed37c546f8dc2f676da7bb
4
+ data.tar.gz: bc86913cf3b560d6eefe94fa722996b7d5442de0200d1060bb5607c1384ad492
5
5
  SHA512:
6
- metadata.gz: cd6b62c587f1ad1ed68b579bfcd70403a916de81593248d4850664b4495dc2ff316d279b338952dfb332f038f1c3b63240907345544298becbf14fe749345806
7
- data.tar.gz: 82fe4b41064b55979b281ad05e48459ae3230e04d91f32065ecab1bf030e337bc56b791a6786ba09fb6bee7b7ec75a808485b8f986713cb888543248278e43f0
6
+ metadata.gz: 931fdeb3e17af3b102cd5cf749530c1c3f8601e3ac9a33dd7e74af53618b0a5d95a68366ec694280052263d06d28f6e073efb11df3a3f1896df69a6dd86b0a20
7
+ data.tar.gz: 1a8e1c80c352bb5e936abe07f922e688e63559e4670d98c2e2e7273f91124e0a16317d946e82638066898a349bf17582c94832a7d5c4a70dddc7b46127bb4c2a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2025-12-30
4
+
5
+ ### Changed
6
+ - **BREAKING**: Upgraded Faraday from 1.x to 2.x (`~> 2.7`)
7
+ - Simplified HTTP request/response handling using Faraday 2.x JSON middleware
8
+ - Refactored `util.rb` to handle pre-parsed JSON responses
9
+
10
+ ### Security
11
+ - Fixed rexml security vulnerability (CVE-2025-58767) by requiring version >= 3.4.2
12
+
13
+ ## [0.3.2] - 2025-01-19
14
+
15
+ ### Added
16
+ - Added `next_billing_at` field support to `Memberships.create` method for setting the next billing date
17
+
3
18
  ## [0.3.1] - 2025-09-04
4
19
 
5
20
  ### Added
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- patch_retention (0.3.1)
5
- faraday (~> 1.10)
4
+ patch_retention (0.4.0)
5
+ faraday (~> 2.7)
6
6
  zeitwerk (~> 2.6)
7
7
 
8
8
  GEM
@@ -23,34 +23,19 @@ GEM
23
23
  rexml
24
24
  diff-lcs (1.5.0)
25
25
  dotenv (2.8.1)
26
- faraday (1.10.4)
27
- faraday-em_http (~> 1.0)
28
- faraday-em_synchrony (~> 1.0)
29
- faraday-excon (~> 1.1)
30
- faraday-httpclient (~> 1.0)
31
- faraday-multipart (~> 1.0)
32
- faraday-net_http (~> 1.0)
33
- faraday-net_http_persistent (~> 1.0)
34
- faraday-patron (~> 1.0)
35
- faraday-rack (~> 1.0)
36
- faraday-retry (~> 1.0)
37
- ruby2_keywords (>= 0.0.4)
38
- faraday-em_http (1.0.0)
39
- faraday-em_synchrony (1.0.1)
40
- faraday-excon (1.1.0)
41
- faraday-httpclient (1.0.1)
42
- faraday-multipart (1.1.1)
43
- multipart-post (~> 2.0)
44
- faraday-net_http (1.0.2)
45
- faraday-net_http_persistent (1.2.0)
46
- faraday-patron (1.0.0)
47
- faraday-rack (1.0.0)
48
- faraday-retry (1.0.3)
26
+ faraday (2.14.0)
27
+ faraday-net_http (>= 2.0, < 3.5)
28
+ json
29
+ logger
30
+ faraday-net_http (3.4.2)
31
+ net-http (~> 0.5)
49
32
  hashdiff (1.2.0)
50
33
  json (2.7.0)
51
34
  language_server-protocol (3.17.0.3)
35
+ logger (1.7.0)
52
36
  method_source (1.0.0)
53
- multipart-post (2.4.1)
37
+ net-http (0.9.1)
38
+ uri (>= 0.11.1)
54
39
  parallel (1.23.0)
55
40
  parser (3.2.2.4)
56
41
  ast (~> 2.4.1)
@@ -63,7 +48,7 @@ GEM
63
48
  rainbow (3.1.1)
64
49
  rake (13.1.0)
65
50
  regexp_parser (2.8.2)
66
- rexml (3.4.1)
51
+ rexml (3.4.4)
67
52
  rspec (3.12.0)
68
53
  rspec-core (~> 3.12.0)
69
54
  rspec-expectations (~> 3.12.0)
@@ -93,9 +78,9 @@ GEM
93
78
  rubocop-shopify (2.15.1)
94
79
  rubocop (~> 1.51)
95
80
  ruby-progressbar (1.13.0)
96
- ruby2_keywords (0.0.5)
97
81
  thor (1.4.0)
98
82
  unicode-display_width (2.5.0)
83
+ uri (1.1.1)
99
84
  vcr (6.3.1)
100
85
  base64
101
86
  webmock (3.25.1)
@@ -115,7 +100,7 @@ DEPENDENCIES
115
100
  patch_retention!
116
101
  pry
117
102
  rake (~> 13.0)
118
- rexml (>= 3.3.9)
103
+ rexml (>= 3.4.2)
119
104
  rspec (~> 3.0)
120
105
  rubocop (~> 1.21)
121
106
  rubocop-shopify (~> 2.15)
data/README.md CHANGED
@@ -278,6 +278,7 @@ membership = PatchRetention::Memberships.create(
278
278
  product_id: "65de5xxxxxxxxxxxxx", # Required, ID of the product (e.g., from product creation)
279
279
  start_at: Time.now.xmlschema, # Optional, ISO8601 timestamp
280
280
  end_at: (Time.now + 30*24*60*60).xmlschema, # Optional, ISO8601 timestamp (e.g., 30 days from now)
281
+ next_billing_at: (Time.now + 7*24*60*60).xmlschema, # Optional, ISO8601 timestamp for next billing date
281
282
  external_id: "MEM123", # Optional
282
283
  data: {
283
284
  "is_trial" => true,
@@ -19,11 +19,10 @@ module PatchRetention
19
19
  payload[:tags] = tags if tags
20
20
 
21
21
  response = PatchRetention.connection(config).post("/v2/calendar_items") do |req|
22
- req.body = payload.to_json
23
- req.headers["Content-Type"] = "application/json"
22
+ req.body = payload
24
23
  end
25
24
 
26
- JSON.parse(response.body)
25
+ response.body
27
26
  rescue Faraday::Error => e
28
27
  raise Error, "Failed to create calendar item: #{e.message}"
29
28
  end
@@ -40,11 +39,10 @@ module PatchRetention
40
39
  payload[:tags] = tags if tags
41
40
 
42
41
  response = PatchRetention.connection(config).patch("/v2/calendar_items/#{calendar_item_id}") do |req|
43
- req.body = payload.to_json
44
- req.headers["Content-Type"] = "application/json"
42
+ req.body = payload
45
43
  end
46
44
 
47
- JSON.parse(response.body)
45
+ response.body
48
46
  rescue Faraday::Error => e
49
47
  raise Error, "Failed to update calendar item: #{e.message}"
50
48
  end
@@ -52,7 +50,7 @@ module PatchRetention
52
50
  def find(calendar_item_id:, config: nil)
53
51
  response = PatchRetention.connection(config).get("/v2/calendar_items/#{calendar_item_id}")
54
52
 
55
- JSON.parse(response.body)
53
+ response.body
56
54
  rescue Faraday::Error => e
57
55
  raise Error, "Failed to find calendar item: #{e.message}"
58
56
  end
@@ -77,7 +75,7 @@ module PatchRetention
77
75
 
78
76
  response = PatchRetention.connection(config).get("/v2/calendar_items", params)
79
77
 
80
- JSON.parse(response.body)
78
+ response.body
81
79
  rescue Faraday::Error => e
82
80
  raise Error, "Failed to retrieve calendar items: #{e.message}"
83
81
  end
@@ -7,7 +7,7 @@ module PatchRetention::Contacts::Update
7
7
  def call(id, contact_params, config = nil)
8
8
  raise_error_if_present do
9
9
  PatchRetention.connection(config).put("#{PatchRetention::Contacts::API_PATH}/#{id}") do |req|
10
- req.body = contact_params.to_json
10
+ req.body = contact_params
11
11
  end
12
12
  end
13
13
  end
@@ -3,24 +3,24 @@
3
3
  module PatchRetention
4
4
  class Memberships
5
5
  class << self
6
- def create(contact_id:, product_id:, start_at: nil, end_at: nil, external_id: nil, tags: nil, data: nil,
7
- config: nil)
6
+ def create(contact_id:, product_id:, start_at: nil, end_at: nil, next_billing_at: nil, external_id: nil,
7
+ tags: nil, data: nil, config: nil)
8
8
  payload = {
9
9
  contact_id: contact_id,
10
10
  product_id: product_id,
11
11
  }
12
12
  payload[:start_at] = start_at if start_at
13
13
  payload[:end_at] = end_at if end_at
14
+ payload[:next_billing_at] = next_billing_at if next_billing_at
14
15
  payload[:external_id] = external_id if external_id
15
16
  payload[:tags] = tags if tags
16
17
  payload[:data] = data if data
17
18
 
18
19
  response = PatchRetention.connection(config).post("/v2/memberships") do |req|
19
- req.body = payload.to_json
20
- req.headers["Content-Type"] = "application/json"
20
+ req.body = payload
21
21
  end
22
22
 
23
- JSON.parse(response.body)
23
+ response.body
24
24
  rescue Faraday::Error => e
25
25
  # You might want to handle different types of Faraday errors differently
26
26
  # or raise a custom error class
@@ -38,11 +38,10 @@ module PatchRetention
38
38
  payload[:status] = status if status
39
39
 
40
40
  response = PatchRetention.connection(config).patch("/v2/memberships/#{membership_id}") do |req|
41
- req.body = payload.to_json
42
- req.headers["Content-Type"] = "application/json"
41
+ req.body = payload
43
42
  end
44
43
 
45
- JSON.parse(response.body)
44
+ response.body
46
45
  rescue Faraday::Error => e
47
46
  raise Error, "Failed to update membership: #{e.message}"
48
47
  end
@@ -50,7 +49,7 @@ module PatchRetention
50
49
  def find(membership_id:, config: nil)
51
50
  response = PatchRetention.connection(config).get("/v2/memberships/#{membership_id}")
52
51
 
53
- JSON.parse(response.body)
52
+ response.body
54
53
  rescue Faraday::Error => e
55
54
  raise Error, "Failed to find membership: #{e.message}"
56
55
  end
@@ -17,11 +17,10 @@ module PatchRetention
17
17
  payload[:external_data] = external_data if external_data
18
18
 
19
19
  response = PatchRetention.connection(config).post("/v2/products") do |req|
20
- req.body = payload.to_json
21
- req.headers["Content-Type"] = "application/json"
20
+ req.body = payload
22
21
  end
23
22
 
24
- JSON.parse(response.body)
23
+ response.body
25
24
  rescue Faraday::Error => e
26
25
  # You might want to handle different types of Faraday errors differently
27
26
  # or raise a custom error class
@@ -41,11 +40,10 @@ module PatchRetention
41
40
  payload[:external_data] = external_data if external_data
42
41
 
43
42
  response = PatchRetention.connection(config).patch("/v2/products/#{product_id}") do |req|
44
- req.body = payload.to_json
45
- req.headers["Content-Type"] = "application/json"
43
+ req.body = payload
46
44
  end
47
45
 
48
- JSON.parse(response.body)
46
+ response.body
49
47
  rescue Faraday::Error => e
50
48
  raise Error, "Failed to update product: #{e.message}"
51
49
  end
@@ -53,7 +51,7 @@ module PatchRetention
53
51
  def find(product_id:, config: nil)
54
52
  response = PatchRetention.connection(config).get("/v2/products/#{product_id}")
55
53
 
56
- JSON.parse(response.body)
54
+ response.body
57
55
  rescue Faraday::Error => e
58
56
  raise Error, "Failed to find product: #{e.message}"
59
57
  end
@@ -11,24 +11,23 @@ module PatchRetention
11
11
  response = yield
12
12
  raise PatchRetention::Error, parse_error_message(response) unless response.status.between?(200, 206)
13
13
 
14
- begin
15
- JSON.parse(response.body)
16
- rescue JSON::ParserError
17
- true
14
+ case response.body
15
+ when Hash, Array then response.body
16
+ else true
18
17
  end
19
18
  end
20
19
 
21
- # Parses the error message from the response.
22
- # Raises a PatchRetention::Error if the response status is 502 and the body is blank.
20
+ # Extracts error message from the response.
23
21
  # @param response [Object] The response to parse the error message from.
24
22
  # @return [String] The error message parsed from the response body.
25
23
  def parse_error_message(response)
26
- if response.status == 502 && response.body.blank?
27
- raise PatchRetention::Error,
28
- "Internal Server Error: Patch API"
24
+ if response.body.is_a?(Hash) && response.body["error"]
25
+ response.body["error"]
26
+ elsif response.status == 502
27
+ "Internal Server Error: Patch API"
28
+ else
29
+ "Request failed with status #{response.status}"
29
30
  end
30
-
31
- JSON.parse(response.body)["error"]
32
31
  end
33
32
  end
34
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PatchRetention
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -37,6 +37,7 @@ module PatchRetention
37
37
  },
38
38
  ) do |builder|
39
39
  builder.request(:json)
40
+ builder.response(:json)
40
41
  end
41
42
  end
42
43
  end
@@ -5,8 +5,8 @@ require_relative "lib/patch_retention/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "patch_retention"
7
7
  spec.version = PatchRetention::VERSION
8
- spec.authors = ["Playbypoint", "Gerardo Ortega"]
9
- spec.email = ["webmaster@playbypoint.com", "g3ortega@gmail.com"]
8
+ spec.authors = ["Playbypoint", "Gerardo Ortega", "Segundo Rebaza"]
9
+ spec.email = ["webmaster@playbypoint.com", "g3ortega@gmail.com", "alvaro.rp1593@gmail.com"]
10
10
 
11
11
  spec.summary = "Patch Retention API wrapper."
12
12
  spec.description = "Patch Retention API wrapper."
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ["lib"]
33
33
 
34
34
  # Runtime dependencies
35
- spec.add_dependency("faraday", "~> 1.10")
35
+ spec.add_dependency("faraday", "~> 2.7")
36
36
  spec.add_dependency("zeitwerk", "~> 2.6")
37
37
 
38
38
  # Development dependencies
@@ -50,7 +50,7 @@ Gem::Specification.new do |spec|
50
50
  spec.add_development_dependency("webmock", "~> 3.0")
51
51
 
52
52
  # Security update for rexml
53
- spec.add_development_dependency("rexml", ">= 3.3.9")
53
+ spec.add_development_dependency("rexml", ">= 3.4.2")
54
54
 
55
55
  # For more information and examples about making a new gem, check out our
56
56
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patch_retention
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Playbypoint
8
8
  - Gerardo Ortega
9
+ - Segundo Rebaza
9
10
  autorequire:
10
11
  bindir: exe
11
12
  cert_chain: []
12
- date: 2025-09-04 00:00:00.000000000 Z
13
+ date: 2025-12-30 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: faraday
@@ -17,14 +18,14 @@ dependencies:
17
18
  requirements:
18
19
  - - "~>"
19
20
  - !ruby/object:Gem::Version
20
- version: '1.10'
21
+ version: '2.7'
21
22
  type: :runtime
22
23
  prerelease: false
23
24
  version_requirements: !ruby/object:Gem::Requirement
24
25
  requirements:
25
26
  - - "~>"
26
27
  - !ruby/object:Gem::Version
27
- version: '1.10'
28
+ version: '2.7'
28
29
  - !ruby/object:Gem::Dependency
29
30
  name: zeitwerk
30
31
  requirement: !ruby/object:Gem::Requirement
@@ -213,18 +214,19 @@ dependencies:
213
214
  requirements:
214
215
  - - ">="
215
216
  - !ruby/object:Gem::Version
216
- version: 3.3.9
217
+ version: 3.4.2
217
218
  type: :development
218
219
  prerelease: false
219
220
  version_requirements: !ruby/object:Gem::Requirement
220
221
  requirements:
221
222
  - - ">="
222
223
  - !ruby/object:Gem::Version
223
- version: 3.3.9
224
+ version: 3.4.2
224
225
  description: Patch Retention API wrapper.
225
226
  email:
226
227
  - webmaster@playbypoint.com
227
228
  - g3ortega@gmail.com
229
+ - alvaro.rp1593@gmail.com
228
230
  executables: []
229
231
  extensions: []
230
232
  extra_rdoc_files: []