linkedin-member-data 0.1.0 → 0.1.1

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: fffdb2d428be752a12be1d391449f8572a2b4d50be3209ef9fed96b3feadf6db
4
- data.tar.gz: 6a0912ba3cefa423ef0de9c86d328f7186b1be45e687a3c1cd9bee95d6adea6d
3
+ metadata.gz: 48d0c94f03bc8e882374452135090bbe2df76a5baac0e8cfa2c008d123034ebe
4
+ data.tar.gz: ccfbec415ec95d7eee0e9af46b9eaa378f980bda8dc50253a5eea0e1a3db52e5
5
5
  SHA512:
6
- metadata.gz: 1c4e4d4bdfb3a8e4d43e5b08aae421dbd7813d81d332ae055749f4dfc054cfb8922f2105cdc954d4e152fc5828458a5a19a43240c929b27c671a75a7ed451969
7
- data.tar.gz: 1102dc284b5355f43ddbcd0ef4d1606cb1cd98473e1a197ec79b884d1a5dc650860c03a8a7551bbbe498f849c7da511540f6eb023e63c2fecade8471ce51f637
6
+ metadata.gz: 56a8ab5192f6465c02626243f9757c702e88d22100510f8e97fda23416e61b87a9c0b6c18b434be5bf30c8b70f5621951206dd5262d79abf8855bd5edf285ab8
7
+ data.tar.gz: d25061a9cc40e04376e3bd528ed8d723a6a92634241d08579de51be73ade3a1c850ad92c1785880a341d24cb291e057aab6ab9f0ec3a7501c4d094a0313d0173
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.1] - 2026-10-06
4
+
5
+ - Reject changelog counts outside 2..50 so a count of 1 cannot silently truncate iteration at the cursor event.
6
+ - Disable Net::HTTP's internal retries so the client's `retries` setting controls all attempts.
7
+ - Reject negative and noninteger retry counts before any request instead of silently skipping requests.
8
+
3
9
  ## [0.1.0] - 2026-10-06
4
10
 
5
11
  - Initial release: Client, Snapshot, Changelog, Authorization, CLI.
data/README.md CHANGED
@@ -69,7 +69,7 @@ Pages are walked until LinkedIn answers "No data found for this memberId". That
69
69
  ## Changelog
70
70
 
71
71
  ```ruby
72
- log = client.changelog(since: Date.new(2026, 9, 1), count: 10) # since: Time, Date or epoch ms; count: 1..50
72
+ log = client.changelog(since: Date.new(2026, 9, 1), count: 10) # since: Time, Date or epoch ms; count: 2..50
73
73
 
74
74
  log.each do |event|
75
75
  event.id; event.method; event.resource_name; event.resource_id
@@ -85,7 +85,7 @@ The API returns the cursor event again on the next page. The gem skips events it
85
85
 
86
86
  `event.method` is the API field (`CREATE`, `UPDATE`, ...). It shadows Ruby's `Object#method` on purpose, so `event.method(:name)` does not work on an Event.
87
87
 
88
- `count` defaults to 10. A value outside 1..50 raises `ArgumentError` before any request.
88
+ `count` defaults to 10. A value outside 2..50 raises `ArgumentError` before any request. A count of 1 cannot advance past the repeated cursor event.
89
89
 
90
90
  Event fields: `id, activity_id, activity_status, config_version, owner, actor, resource_name, resource_id, resource_uri, method, method_name, captured_at, processed_at, activity, processed_activity, sibling_activities, parent_sibling_activities, raw`.
91
91
 
@@ -123,6 +123,8 @@ LinkedIn::MemberData::Client.new(
123
123
 
124
124
  Retries wait for `Retry-After` when it is present, capped at 60 seconds. Otherwise the wait grows with each try (exponential backoff).
125
125
 
126
+ `retries` must be a nonnegative integer; invalid values raise `ArgumentError` when the client is created. Net::HTTP's internal retries are disabled so this option controls every retry.
127
+
126
128
  ## Errors
127
129
 
128
130
  ```
data/doc/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.1] - 2026-10-06
4
+
5
+ - Reject changelog counts outside 2..50 so a count of 1 cannot silently truncate iteration at the cursor event.
6
+ - Disable Net::HTTP's internal retries so the client's `retries` setting controls all attempts.
7
+ - Reject negative and noninteger retry counts before any request instead of silently skipping requests.
8
+
3
9
  ## [0.1.0] - 2026-10-06
4
10
 
5
11
  - Initial release: Client, Snapshot, Changelog, Authorization, CLI.
@@ -45,13 +45,13 @@ API path of the changelog resource.
45
45
  ### `count` [R] <a id="attribute-i-count"></a> <a id="count-instance_method"></a>
46
46
  Settings of this view. `since` is the first `processedAt` to fetch, in epoch
47
47
  milliseconds (`nil` starts at the oldest event). `count` is the number of
48
- events per request, from 1 to 50.
48
+ events per request, from 2 to 50.
49
49
  - **@return** [Integer, nil] `since` or `count`. `count` is never nil.
50
50
 
51
51
  ### `since` [R] <a id="attribute-i-since"></a> <a id="since-instance_method"></a>
52
52
  Settings of this view. `since` is the first `processedAt` to fetch, in epoch
53
53
  milliseconds (`nil` starts at the oldest event). `count` is the number of
54
- events per request, from 1 to 50.
54
+ events per request, from 2 to 50.
55
55
  - **@return** [Integer, nil] `since` or `count`. `count` is never nil.
56
56
 
57
57
  ## Public Instance Methods
@@ -36,8 +36,8 @@ Returns a lazy view over the changelog of the last 28 days. No request is sent
36
36
  until you iterate.
37
37
  - **@param** `since` [Time, Date, Integer, nil] first `processedAt` to fetch.
38
38
  Integer is epoch milliseconds. A Date is midnight UTC. `nil` starts at the oldest event.
39
- - **@param** `count` [Integer] events per request, from 1 to 50.
40
- - **@raise** [ArgumentError] when `count` is outside 1..50 or `since` has an unsupported type.
39
+ - **@param** `count` [Integer] events per request, from 2 to 50.
40
+ - **@raise** [ArgumentError] when `count` is outside 2..50 or `since` has an unsupported type.
41
41
  Raised before any request.
42
42
  - **@return** [Changelog]
43
43
 
data/doc/README.md CHANGED
@@ -69,7 +69,7 @@ Pages are walked until LinkedIn answers "No data found for this memberId". That
69
69
  ## Changelog
70
70
 
71
71
  ```ruby
72
- log = client.changelog(since: Date.new(2026, 9, 1), count: 10) # since: Time, Date or epoch ms; count: 1..50
72
+ log = client.changelog(since: Date.new(2026, 9, 1), count: 10) # since: Time, Date or epoch ms; count: 2..50
73
73
 
74
74
  log.each do |event|
75
75
  event.id; event.method; event.resource_name; event.resource_id
@@ -85,7 +85,7 @@ The API returns the cursor event again on the next page. The gem skips events it
85
85
 
86
86
  `event.method` is the API field (`CREATE`, `UPDATE`, ...). It shadows Ruby's `Object#method` on purpose, so `event.method(:name)` does not work on an Event.
87
87
 
88
- `count` defaults to 10. A value outside 1..50 raises `ArgumentError` before any request.
88
+ `count` defaults to 10. A value outside 2..50 raises `ArgumentError` before any request. A count of 1 cannot advance past the repeated cursor event.
89
89
 
90
90
  Event fields: `id, activity_id, activity_status, config_version, owner, actor, resource_name, resource_id, resource_uri, method, method_name, captured_at, processed_at, activity, processed_activity, sibling_activities, parent_sibling_activities, raw`.
91
91
 
@@ -123,6 +123,8 @@ LinkedIn::MemberData::Client.new(
123
123
 
124
124
  Retries wait for `Retry-After` when it is present, capped at 60 seconds. Otherwise the wait grows with each try (exponential backoff).
125
125
 
126
+ `retries` must be a nonnegative integer; invalid values raise `ArgumentError` when the client is created. Net::HTTP's internal retries are disabled so this option controls every retry.
127
+
126
128
  ## Errors
127
129
 
128
130
  ```
@@ -31,7 +31,7 @@ module LinkedIn
31
31
 
32
32
  # Allowed values for `count`.
33
33
  # @return [Range<Integer>]
34
- COUNT_RANGE = (1..50)
34
+ COUNT_RANGE = (2..50)
35
35
 
36
36
  # Default for `count`.
37
37
  # @return [Integer]
@@ -72,7 +72,7 @@ module LinkedIn
72
72
  private_constant :Walk
73
73
 
74
74
  # Settings of this view. `since` is the first `processedAt` to fetch, in epoch milliseconds
75
- # (`nil` starts at the oldest event). `count` is the number of events per request, from 1 to 50.
75
+ # (`nil` starts at the oldest event). `count` is the number of events per request, from 2 to 50.
76
76
  # @return [Integer, nil] `since` or `count`. `count` is never nil.
77
77
  attr_reader :since, :count
78
78
 
@@ -80,8 +80,8 @@ module LinkedIn
80
80
  # @param connection [Connection] used for every request.
81
81
  # @param since [Time, Date, Integer, nil] first `processedAt` to fetch.
82
82
  # Integer is epoch milliseconds. A Date is midnight UTC.
83
- # @param count [Integer] events per request, from 1 to 50.
84
- # @raise [ArgumentError] when `count` is outside 1..50 or `since` has an unsupported type.
83
+ # @param count [Integer] events per request, from 2 to 50. One slot is needed for the cursor overlap.
84
+ # @raise [ArgumentError] when `count` is outside 2..50 or `since` has an unsupported type.
85
85
  # Raised before any request.
86
86
  def initialize(connection, since: nil, count: DEFAULT_COUNT)
87
87
  @count = count
@@ -9,7 +9,7 @@ module LinkedIn
9
9
  # @return [Array<Array>]
10
10
  OPTIONS = [
11
11
  ["--since DATE", SinceParser, "ISO date or datetime"],
12
- ["--count N", Integer, "Events per request (1..50)"],
12
+ ["--count N", Integer, "Events per request (2..50)"],
13
13
  ["--out FILE", "Write to FILE instead of stdout"]
14
14
  ].freeze
15
15
 
@@ -58,9 +58,9 @@ module LinkedIn
58
58
  # client.changelog(since: last_seen).each { |event| puts event.id }
59
59
  # @param since [Time, Date, Integer, nil] first `processedAt` to fetch.
60
60
  # Integer is epoch milliseconds. A Date is midnight UTC. `nil` starts at the oldest event.
61
- # @param count [Integer] events per request, from 1 to 50.
61
+ # @param count [Integer] events per request, from 2 to 50.
62
62
  # @return [Changelog]
63
- # @raise [ArgumentError] when `count` is outside 1..50 or `since` has an unsupported type.
63
+ # @raise [ArgumentError] when `count` is outside 2..50 or `since` has an unsupported type.
64
64
  # Raised before any request.
65
65
  def changelog(since: nil, count: Changelog::DEFAULT_COUNT)
66
66
  Changelog.new(connection, since: since, count: count)
@@ -45,7 +45,7 @@ module LinkedIn
45
45
  # @return [Net::HTTPResponse]
46
46
  def call(request, uri)
47
47
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: @timeout,
48
- read_timeout: @timeout, write_timeout: @timeout) do |http|
48
+ read_timeout: @timeout, write_timeout: @timeout, max_retries: 0) do |http|
49
49
  http.request(request)
50
50
  end
51
51
  end
@@ -83,12 +83,15 @@ module LinkedIn
83
83
 
84
84
  # @param access_token [String] OAuth token. Sent as a Bearer header.
85
85
  # @param retries [Integer] retries on 429, 5xx and network errors. `0` turns retries off.
86
+ # Must be a nonnegative integer.
86
87
  # @param timeout [Integer, Float] timeout in seconds for the default transport.
87
88
  # @param logger [Logger, nil] gets one debug line per request.
88
89
  # @param sleeper [#call] called with the seconds to wait between retries.
89
90
  # @param transport [#call] takes `(request, uri)` and returns a response. Replaced in tests.
90
91
  def initialize(access_token:, retries: 3, timeout: 30, logger: nil, sleeper: Kernel.method(:sleep),
91
92
  transport: NetHttpTransport.new(timeout: timeout))
93
+ raise ArgumentError, "retries must be a nonnegative integer" unless retries.is_a?(Integer) && retries >= 0
94
+
92
95
  @headers = HEADERS.merge("Authorization" => "Bearer #{access_token}")
93
96
  @retrier = Retrier.new(retries: retries, sleeper: sleeper)
94
97
  @logger = logger
@@ -11,6 +11,6 @@ module LinkedIn
11
11
  module MemberData
12
12
  # Gem version.
13
13
  # @return [String]
14
- VERSION = "0.1.0"
14
+ VERSION = "0.1.1"
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linkedin-member-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucian Ghinda