smplkit 3.0.96 → 3.0.97

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: a1d765730dd1bb26ebf38f16627878d7d33220bc20bd005b98b12303a18e88c1
4
- data.tar.gz: 1109c9cd1b02865ae3d2148a8232509b185d828ed8762c025cf82dcfc9c9c09e
3
+ metadata.gz: c317a0f573d990742547e60f7e17bba0bd65a6abc13dae8bcf8ab13ca7e167e3
4
+ data.tar.gz: c02f2385189d409d3f1a8263156f0a659e55ae762d4c2f9940bdf6a51d61f19d
5
5
  SHA512:
6
- metadata.gz: '099f6f60a8acdbd5804cd32743d7f6d6e28261de9901f08a354536da0e49a8b3cec0809790106b072cd7275daa60fdd4279b979dca22590ae74d87382bed04ed'
7
- data.tar.gz: '089e631caa282df42aea0344a2e38fe17795e2d773d6799e6684ee1d389d418b0d4c1714fcf398c70b8961fdd4919b11c1b7b56f26b8e7a6e1b631853ac12447'
6
+ metadata.gz: 33f03cf3bde2e7a38b9856b558be13546c374ceddec2c02ec9cb5d454922f373d46f39188e86ffbbba194421318b9d04bba1a966ac2930ad088c6cf46f6d7cf5
7
+ data.tar.gz: 91337cdc5b3da03eae931e8b67b7454d0d04925e667446b49ba003ecd0c6bcd091f319f15df58d2c926f818a563a5ab4648ef769261ffacc9422636f125dd3a6
@@ -9,9 +9,11 @@ module Smplkit
9
9
  #
10
10
  # +base_url+/+api_key+ are used directly when both are supplied (the path
11
11
  # the top-level client takes after it has already resolved them); otherwise
12
- # the management config resolver fills in whatever is missing.
12
+ # the config resolver fills in whatever is missing.
13
+ #
14
+ # @api private
13
15
  def self.resolve_account_target(api_key:, base_url:, profile:, base_domain:, scheme:, debug:, extra_headers:)
14
- cfg = ConfigResolution.resolve_management_config(
16
+ cfg = ConfigResolution.resolve_client_config(
15
17
  profile: profile, api_key: api_key, base_domain: base_domain, scheme: scheme, debug: debug
16
18
  )
17
19
  resolved_key = api_key.nil? ? cfg.api_key : api_key
@@ -37,12 +39,17 @@ module Smplkit
37
39
  }.merge(extra_headers || {})
38
40
  end
39
41
 
42
+ # Fetch the authenticated account's current settings.
43
+ #
44
+ # @return [Smplkit::Account::AccountSettings] An active record. Mutate its
45
+ # fields and call +save+ to persist the changes.
40
46
  def get
41
47
  resp = connection.get(SETTINGS_PATH)
42
48
  Errors.raise_for_status(resp.status, resp.body.to_s)
43
49
  AccountSettings.new(self, data: parse_body(resp.body))
44
50
  end
45
51
 
52
+ # @api private
46
53
  def _save(data)
47
54
  resp = connection.put(SETTINGS_PATH) { |req| req.body = JSON.generate(data) }
48
55
  Errors.raise_for_status(resp.status, resp.body.to_s)
@@ -14,23 +14,40 @@ module Smplkit
14
14
  end
15
15
 
16
16
  # The full settings dict. Mutations are persisted on save.
17
+ #
18
+ # @return [Hash] The full settings dict.
17
19
  def raw
18
20
  @data
19
21
  end
20
22
 
23
+ # Replace the full settings dict.
24
+ #
25
+ # @param value [Hash] The new settings dict.
26
+ # @return [void]
21
27
  def raw=(value)
22
28
  @data = value.dup
23
29
  end
24
30
 
25
31
  # Canonical ordering of STANDARD environments. Empty list if unset.
32
+ #
33
+ # @return [Array<String>] The environment ids in canonical order.
26
34
  def environment_order
27
35
  Array(@data["environment_order"] || [])
28
36
  end
29
37
 
38
+ # Set the canonical ordering of STANDARD environments.
39
+ #
40
+ # @param value [Array<String>] The environment ids in canonical order.
41
+ # @return [void]
30
42
  def environment_order=(value)
31
43
  @data["environment_order"] = value.to_a
32
44
  end
33
45
 
46
+ # Write the full settings object back to the account.
47
+ #
48
+ # @return [AccountSettings] +self+, updated with the server response.
49
+ # @raise [RuntimeError] If this model was constructed without a client
50
+ # (e.g. built by hand rather than returned from +get+).
34
51
  def save
35
52
  raise "AccountSettings was constructed without a client; cannot save" if @client.nil?
36
53
 
@@ -45,6 +62,7 @@ module Smplkit
45
62
  end
46
63
  alias inspect to_s
47
64
 
65
+ # @api private
48
66
  def _apply(other)
49
67
  @data = other.raw.dup
50
68
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Smplkit
4
4
  # Ruby-internal adapters bridging the generated client layer to the wrapper.
5
+ #
6
+ # @api private
5
7
  module ApiSupport
6
8
  # Default page[size] the runtime asks for when walking a list endpoint to
7
9
  # completion. The platform caps page[size] at 1000; using the same value
@@ -14,6 +16,8 @@ module Smplkit
14
16
  # status-coded failures route through +Errors.raise_for_status+ which emits
15
17
  # +NotFoundError+ / +ConflictError+ / +ValidationError+ / +Error+ depending
16
18
  # on the JSON:API body.
19
+ #
20
+ # @api private
17
21
  module ErrorMapping
18
22
  module_function
19
23
 
@@ -44,6 +48,8 @@ module Smplkit
44
48
  # server returns fewer rows than requested — the platform's standard
45
49
  # last-page signal across every offset-paginated list endpoint. Returns the
46
50
  # concatenated +response.data+ rows.
51
+ #
52
+ # @api private
47
53
  module PaginatedFetch
48
54
  module_function
49
55
 
@@ -65,6 +71,8 @@ module Smplkit
65
71
 
66
72
  # Deep-stringify Hash keys so resources returned by generated +to_hash+
67
73
  # (symbol-keyed) match what the wrapper helpers expect (string-keyed).
74
+ #
75
+ # @api private
68
76
  module ResourceShim
69
77
  module_function
70
78
 
@@ -3,13 +3,15 @@
3
3
  module Smplkit
4
4
  module Audit
5
5
  # Bounded in-memory queue + worker thread for fire-and-forget audit
6
- # emits (ADR-047 §2.6).
6
+ # emits.
7
7
  #
8
8
  # +#enqueue+ returns immediately. The worker drains on either a
9
9
  # periodic tick or once depth crosses the high-water mark, retries
10
10
  # transient failures with exponential backoff, drops permanent 4xx
11
11
  # (other than 429), and evicts the oldest item under sustained
12
12
  # back-pressure.
13
+ #
14
+ # @api private
13
15
  class EventBuffer
14
16
  MAX_BUFFER_SIZE = 1000
15
17
  WATERMARK = 50
@@ -5,21 +5,32 @@ module Smplkit
5
5
  # +client.audit.categories.list+ — distinct +category+ values seen for
6
6
  # the account.
7
7
  #
8
- # Backed by a maintain-by-write side table populated whenever an event
9
- # is recorded with a non-null +category+ (ADR-047 §2.5), so the response
10
- # time is independent of how many years of events the account has
11
- # accumulated. Sorted alphabetically; offset pagination (+page_number+ /
12
- # +page_size+) per ADR-014.
8
+ # Response time is independent of how many years of events the account has
9
+ # accumulated. Sorted alphabetically; offset paginated.
13
10
  class Categories
14
11
  def initialize(api)
15
12
  @api = api
16
13
  end
17
14
 
18
- # +environments+ is an optional array of environment keys (and/or the
19
- # reserved +"smplkit"+ control-plane bucket) used to scope the read;
20
- # the values are comma-joined into +filter[environment]+. Omitting it
21
- # (or passing an empty array) leaves the filter unset — identical to
22
- # the prior behavior on the wire.
15
+ # List the distinct +category+ values seen in the account.
16
+ #
17
+ # +environments+ scopes the listing to a set of environments: pass an
18
+ # array of environment keys and/or the reserved +"smplkit"+ control-plane
19
+ # bucket; the values are comma-joined into +filter[environment]+. Omitting
20
+ # it (or passing an empty array) leaves the filter off entirely.
21
+ #
22
+ # @param page_number [Integer, nil] 1-based page index. Omit for the first
23
+ # page.
24
+ # @param page_size [Integer, nil] Maximum number of categories to return in
25
+ # this page.
26
+ # @param meta_total [Boolean, nil] When +true+, populate +total+ and
27
+ # +total_pages+ in the returned page's +pagination+ block (costs an extra
28
+ # count server-side). Omit to skip it.
29
+ # @param environments [Array<String>, nil] Environment keys and/or the
30
+ # reserved +"smplkit"+ control-plane bucket to scope the listing to. Omit
31
+ # to leave the filter off entirely.
32
+ # @return [Smplkit::Audit::CategoryListPage] A page of the matching
33
+ # category values.
23
34
  def list(page_number: nil, page_size: nil, meta_total: nil, environments: nil)
24
35
  opts = {}
25
36
  opts[:page_number] = page_number if page_number
@@ -4,12 +4,22 @@ module Smplkit
4
4
  module Audit
5
5
  # The Smpl Audit client — accessed via +client.audit+.
6
6
  #
7
- # One client exposes the full surface — there is no runtime/management
8
- # split for audit. Owns event recording and read-side queries:
9
- # fire-and-forget +#events.record+, plus the audit-log +list+ / +get+ and
10
- # the distinct-value listings (+resource_types+, +event_types+,
11
- # +categories+) that back the Activity tab filter dropdowns, plus SIEM
12
- # forwarder CRUD on +#forwarders+. ADR-047 §2.7.
7
+ # One client exposes the full surface — event recording and reads,
8
+ # distinct-value discovery, and SIEM forwarder CRUD. Owns fire-and-forget
9
+ # +#events.record+, plus the audit-log +list+ / +get+ and the distinct-value
10
+ # listings (+resource_types+, +event_types+, +categories+), plus SIEM
11
+ # forwarder CRUD on +#forwarders+.
12
+ #
13
+ # @param api_key [String] API key used to authenticate every request.
14
+ # @param base_url [String] Full audit-service base URL.
15
+ # @param environment [String, nil] Deployment environment to scope recording
16
+ # and reads to. Optional — forwarder CRUD and discovery are
17
+ # environment-agnostic, and reads accept an explicit +environments: [...]+
18
+ # filter.
19
+ # @param timeout [Float] Per-request timeout, in seconds. Defaults to +10.0+.
20
+ # @param extra_headers [Hash{String => String}, nil] Extra headers attached
21
+ # to every request. SDK-owned headers (authorization, content-type,
22
+ # user-agent) cannot be overridden.
13
23
  class AuditClient
14
24
  attr_reader :events, :resource_types, :event_types, :categories, :forwarders
15
25
 
@@ -7,22 +7,38 @@ module Smplkit
7
7
  #
8
8
  # Without +filter_resource_type+, returns one row per distinct
9
9
  # event type — an event type recorded with multiple resource_types appears
10
- # once. With the filter, returns the event types seen with that
11
- # specific resource_type, powering the cascading-filter behavior
12
- # on the Activity tab.
10
+ # once. With the filter, returns the event types seen with that specific
11
+ # resource_type, which supports building a cascading resource-type-then-
12
+ # event-type filter.
13
13
  #
14
- # ADR-047 §2.5. Sorted alphabetically; offset pagination
15
- # (+page_number+ / +page_size+) per ADR-014.
14
+ # Sorted alphabetically; offset paginated.
16
15
  class EventTypes
17
16
  def initialize(api)
18
17
  @api = api
19
18
  end
20
19
 
21
- # +environments+ is an optional array of environment keys (and/or the
22
- # reserved +"smplkit"+ control-plane bucket) used to scope the read;
23
- # the values are comma-joined into +filter[environment]+. Omitting it
24
- # (or passing an empty array) leaves the filter unset — identical to
25
- # the prior behavior on the wire.
20
+ # List the distinct +event_type+ slugs seen in the account.
21
+ #
22
+ # +environments+ scopes the listing to a set of environments: pass an
23
+ # array of environment keys and/or the reserved +"smplkit"+ control-plane
24
+ # bucket; the values are comma-joined into +filter[environment]+. Omitting
25
+ # it (or passing an empty array) leaves the filter off entirely.
26
+ #
27
+ # @param filter_resource_type [String, nil] Restrict the listing to
28
+ # event_types seen with this +resource_type+. Omit to list every distinct
29
+ # event_type.
30
+ # @param page_number [Integer, nil] 1-based page index. Omit for the first
31
+ # page.
32
+ # @param page_size [Integer, nil] Maximum number of slugs to return in this
33
+ # page.
34
+ # @param meta_total [Boolean, nil] When +true+, populate +total+ and
35
+ # +total_pages+ in the returned page's +pagination+ block (costs an extra
36
+ # count server-side). Omit to skip it.
37
+ # @param environments [Array<String>, nil] Environment keys and/or the
38
+ # reserved +"smplkit"+ control-plane bucket to scope the listing to. Omit
39
+ # to leave the filter off entirely.
40
+ # @return [Smplkit::Audit::EventTypeListPage] A page of the matching
41
+ # event-type slugs.
26
42
  def list(filter_resource_type: nil, page_number: nil, page_size: nil, meta_total: nil, environments: nil)
27
43
  opts = {}
28
44
  opts[:filter_resource_type] = filter_resource_type if filter_resource_type
@@ -4,9 +4,9 @@ module Smplkit
4
4
  module Audit
5
5
  # Audit events surface — accessed via +client.audit.events+.
6
6
  #
7
- # +#record+ is fire-and-forget per ADR-047 §2.6 the call enqueues
8
- # the event onto an in-memory bounded buffer and returns
9
- # immediately. +#list+ and +#get+ are synchronous reads.
7
+ # +#record+ is fire-and-forget the call enqueues the event onto an
8
+ # in-memory bounded buffer and returns immediately. +#list+ and +#get+
9
+ # are synchronous reads.
10
10
  class Events
11
11
  def initialize(api)
12
12
  @api = api
@@ -15,18 +15,53 @@ module Smplkit
15
15
 
16
16
  # Enqueue an audit event for asynchronous delivery.
17
17
  #
18
+ # Returns immediately — the buffer's worker thread performs the actual
19
+ # POST with retry on transient failures.
20
+ #
18
21
  # Actor attribution (+actor_type+, +actor_id+, +actor_label+) is
19
22
  # customer-supplied and free-form. The audit service stores
20
23
  # whatever the caller passed and never backfills from the request
21
24
  # credential — supply the fields explicitly when you want the
22
25
  # event attributed.
23
26
  #
24
- # Customer attempts to record events with +resource_type+ starting
25
- # with +smpl.+ are rejected by the server with a 403 (the buffer
26
- # logs and drops permanent failures).
27
+ # @param event_type [String] What happened (e.g. +"invoice.created"+).
28
+ # Any non-empty string.
29
+ # @param resource_type [String] Kind of resource the event is about (e.g.
30
+ # +"invoice"+). Any non-empty string. Customer events must NOT use the
31
+ # +smpl.+ prefix — that namespace is reserved for smplkit-emitted events
32
+ # and the server rejects customer attempts with a 403 (the buffer logs
33
+ # and drops permanent failures).
34
+ # @param resource_id [String] Identifier of the affected resource.
35
+ # @param occurred_at [Time, DateTime, String, nil] When the event happened
36
+ # in the originating system. Defaults to +now+ server-side if omitted.
37
+ # @param actor_type [String, nil] Free-form label for the kind of actor
38
+ # that caused the event (e.g. +"USER"+, +"API_KEY"+, +"SYSTEM"+, or any
39
+ # custom value). The audit service never backfills this from the request
40
+ # credential — supply it explicitly when you want the event attributed.
41
+ # @param actor_id [String, nil] Free-form identifier of the actor that
42
+ # caused the event. Any string scheme is accepted.
43
+ # @param actor_label [String, nil] Human-readable label for the actor
44
+ # (e.g. an email address or API key name).
45
+ # @param category [String, nil] Optional free-form bucket label for the
46
+ # event (e.g. +"auth"+, +"billing"+, +"config-change"+). Stored exactly
47
+ # as supplied; powers the audit log's category filter and the
48
+ # +categories+ discovery listing ({Smplkit::Audit::AuditClient#categories}).
49
+ # Omit it to leave the event uncategorized.
50
+ # @param data [Hash, nil] Free-form contextual JSON. To record a resource
51
+ # snapshot, place it inside +data+ — smplkit's own convention nests it at
52
+ # +data["snapshot"]+ for consistency, but the shape is unconstrained.
53
+ # @param idempotency_key [String, nil] Optional caller-supplied idempotency
54
+ # key. If omitted, the server derives one from event content (account_id
55
+ # + event_type + resource_type + resource_id + occurred_at + actor_* +
56
+ # data).
57
+ # @param do_not_forward [Boolean] When +true+, the audit service records
58
+ # the event normally but does NOT POST it through any configured SIEM
59
+ # forwarder. A +skipped_do_not_forward+ delivery row is recorded for each
60
+ # enabled forwarder so the skip is visible in the forwarder delivery log.
61
+ # @return [void]
27
62
  def record(event_type:, resource_type:, resource_id:,
28
63
  occurred_at: nil, actor_type: nil, actor_id: nil,
29
- actor_label: nil, data: nil, idempotency_key: nil,
64
+ actor_label: nil, category: nil, data: nil, idempotency_key: nil,
30
65
  do_not_forward: false)
31
66
  raise ArgumentError, "event_type is required" if event_type.nil? || event_type.to_s.empty?
32
67
  raise ArgumentError, "resource_type is required" if resource_type.nil? || resource_type.to_s.empty?
@@ -55,6 +90,7 @@ module Smplkit
55
90
  actor_type: actor_type,
56
91
  actor_id: actor_id,
57
92
  actor_label: actor_label,
93
+ category: category,
58
94
  data: data || {},
59
95
  do_not_forward: do_not_forward
60
96
  )
@@ -69,22 +105,55 @@ module Smplkit
69
105
 
70
106
  # Single-event retrieval.
71
107
  #
72
- # Raises {Smplkit::NotFoundError} when no event with that id
73
- # exists in the caller's account.
108
+ # @param event_id [String] The event's UUID, as a string parseable as one.
109
+ # @return [Smplkit::Audit::AuditEvent] The matching event.
110
+ # @raise [Smplkit::NotFoundError] If no event with that id exists in the
111
+ # caller's account.
74
112
  def get(event_id)
75
113
  resp = Smplkit::Audit.call_api { @api.get_event(event_id) }
76
114
  AuditEvent.from_resource(resp.data)
77
115
  end
78
116
 
79
- # List events with filters and cursor pagination. Returns a
80
- # +Smplkit::Audit::ListEventsPage+ whose +#events+ is the page and
81
- # +#next_cursor+ is the opaque token for the next page (or nil).
117
+ # List audit events for the authenticated account.
118
+ #
119
+ # Filters apply server-side. +actor_id+ is matched as a literal string
120
+ # against whatever the recording call stored. Pagination uses an opaque
121
+ # cursor (+page_after+); the returned page exposes +#next_cursor+ when
122
+ # more pages are available.
123
+ #
124
+ # +search+ is an optional free-text filter: pass a string to return only
125
+ # events whose +resource_id+ or +description+ contains it as a
126
+ # case-insensitive substring; omit it (the default) to disable text
127
+ # filtering. A +search+ filter must be scoped — combine it with
128
+ # +occurred_at_range+, or with both +resource_type+ and +resource_id+ —
129
+ # or the request is rejected.
82
130
  #
83
- # +environments+ is an optional array of environment keys (and/or the
84
- # reserved +"smplkit"+ control-plane bucket) used to scope the read; the
85
- # values are comma-joined into +filter[environment]+. Omitting it (or
86
- # passing an empty array) leaves the filter unset — identical to the
87
- # prior behavior on the wire.
131
+ # @param event_type [String, nil] Return only events with this
132
+ # +event_type+. Omit to match any.
133
+ # @param resource_type [String, nil] Return only events about this
134
+ # +resource_type+. Omit to match any.
135
+ # @param resource_id [String, nil] Return only events about this resource
136
+ # id. Omit to match any.
137
+ # @param actor_type [String, nil] Return only events whose +actor_type+
138
+ # equals this value. Omit to match any.
139
+ # @param actor_id [String, nil] Return only events whose +actor_id+
140
+ # matches this value as a literal string. Omit to match any.
141
+ # @param occurred_at_range [String, nil] Restrict to events whose
142
+ # +occurred_at+ falls in this range. Omit to leave the time window open.
143
+ # @param search [String, nil] Optional free-text filter — returns only
144
+ # events whose +resource_id+ or +description+ contains it as a
145
+ # case-insensitive substring. Must be scoped (combine with
146
+ # +occurred_at_range+, or with both +resource_type+ and +resource_id+)
147
+ # or the request is rejected. Omit to disable text filtering.
148
+ # @param environments [Array<String>, nil] Environment keys (and/or the
149
+ # reserved +"smplkit"+ control-plane bucket) to scope the read to. Omit
150
+ # to leave the filter off entirely.
151
+ # @param page_size [Integer, nil] Maximum number of events to return in
152
+ # this page.
153
+ # @param page_after [String, nil] Opaque cursor from a previous page's
154
+ # +next_cursor+. Omit for the first page.
155
+ # @return [Smplkit::Audit::ListEventsPage] A page of the matching events;
156
+ # its +#next_cursor+ is set when more pages are available.
88
157
  def list(event_type: nil, resource_type: nil, resource_id: nil,
89
158
  actor_type: nil, actor_id: nil, occurred_at_range: nil,
90
159
  search: nil, environments: nil, page_size: nil, page_after: nil)
@@ -112,6 +181,13 @@ module Smplkit
112
181
  end
113
182
 
114
183
  # Block until the in-memory buffer is drained or the timeout elapses.
184
+ #
185
+ # Useful for draining buffered events at process shutdown or after a batch
186
+ # of fire-and-forget records.
187
+ #
188
+ # @param timeout [Float, nil] Upper bound on the blocking flush, in
189
+ # seconds. +nil+ blocks indefinitely. Defaults to +5.0+.
190
+ # @return [void]
115
191
  def flush(timeout: 5.0)
116
192
  @buffer.flush(timeout: timeout)
117
193
  end
@@ -34,8 +34,9 @@ module Smplkit
34
34
  # @param name [String] Display name. Defaults to +id+ when not supplied.
35
35
  # @param forwarder_type [String] One of {Smplkit::Audit::ForwarderType::VALUES}.
36
36
  # @param configuration [Smplkit::Audit::HttpConfiguration] Destination
37
- # request configuration. Headers carry credentials and are encrypted at
38
- # rest server-side; reads return them redacted.
37
+ # request configuration. Header values often carry credentials and are
38
+ # returned in plaintext on reads, so a get-mutate-put round-trip
39
+ # preserves them without re-entering secrets.
39
40
  # @param environments [Hash{String => Smplkit::Audit::ForwarderEnvironment, Hash}, nil]
40
41
  # Per-environment overrides keyed by environment key (e.g.
41
42
  # +"production"+). A forwarder delivers in an environment only when that
@@ -85,12 +86,19 @@ module Smplkit
85
86
 
86
87
  # List forwarders for the authenticated account.
87
88
  #
88
- # Offset paginated per ADR-014: pass +page_number+ (1-based) and
89
- # +page_size+ (default 1000, max 1000). Pass +meta_total: true+ to populate
90
- # +total+ and +total_pages+ in the returned +pagination+ block (costs an
91
- # extra COUNT query server-side).
89
+ # Offset paginated: pass +page_number+ (1-based) and +page_size+
90
+ # (default 1000, max 1000).
92
91
  #
93
- # @return [ForwarderListPage]
92
+ # @param forwarder_type [String, nil] Restrict the listing to forwarders of
93
+ # this {Smplkit::Audit::ForwarderType}. Omit to list every type.
94
+ # @param page_number [Integer, nil] 1-based page index. Omit for the first
95
+ # page.
96
+ # @param page_size [Integer, nil] Maximum number of forwarders to return in
97
+ # this page (default 1000, max 1000).
98
+ # @param meta_total [Boolean, nil] When +true+, populate +total+ and
99
+ # +total_pages+ in the returned page's +pagination+ block (costs an extra
100
+ # count server-side). Omit to skip it.
101
+ # @return [ForwarderListPage] A page of the matching forwarders.
94
102
  def list(forwarder_type: nil, page_number: nil, page_size: nil, meta_total: nil)
95
103
  opts = {}
96
104
  opts[:filter_forwarder_type] = ForwarderType.coerce(forwarder_type) if forwarder_type
@@ -104,16 +112,19 @@ module Smplkit
104
112
  end
105
113
 
106
114
  # Fetch a single forwarder by id. The returned instance is bound to this
107
- # client, so +forwarder.save+ and +forwarder.delete+ work.
115
+ # client, so +forwarder.save+ and +forwarder.delete+ work. Header values
116
+ # come back in plaintext, so mutating the returned forwarder and calling
117
+ # +save+ preserves them without re-entering secrets.
108
118
  #
109
- # @param forwarder_id [String]
110
- # @return [Smplkit::Audit::Forwarder]
119
+ # @param forwarder_id [String] The forwarder's id (key).
120
+ # @return [Smplkit::Audit::Forwarder] The matching forwarder, bound to this client.
121
+ # @raise [Smplkit::NotFoundError] If no live forwarder with that id exists.
111
122
  def get(forwarder_id)
112
123
  resp = Audit.call_api { @api.get_forwarder(forwarder_id) }
113
124
  Forwarder.from_resource(resp.data, client: self)
114
125
  end
115
126
 
116
- # Soft-delete a forwarder.
127
+ # Delete a forwarder.
117
128
  #
118
129
  # @param forwarder_id [String]
119
130
  # @return [nil]
@@ -136,9 +147,9 @@ module Smplkit
136
147
  # @api private — Full-replace PUT for an existing forwarder. Called by
137
148
  # {Smplkit::Audit::Forwarder#save} on instances with +created_at+.
138
149
  #
139
- # Header values must be re-supplied as plaintext; the GET path redacts
140
- # them, so a PUT body containing +"<redacted>"+ would persist that literal.
141
- # Track real header values client-side and round-trip them.
150
+ # Header values come back in plaintext on the GET path, so a fetched
151
+ # forwarder round-trips through this full-replace PUT with its header
152
+ # values intact no need to re-enter secrets.
142
153
  def _update_forwarder(forwarder)
143
154
  raise ArgumentError, "cannot update a Forwarder with no id" if forwarder.id.nil?
144
155
 
@@ -183,8 +194,8 @@ module Smplkit
183
194
  end
184
195
 
185
196
  def build_attrs(forwarder)
186
- # The base ``enabled`` is server-pinned false (ADR-055); we don't send
187
- # it. Enablement travels entirely through ``environments``.
197
+ # The base +enabled+ is server-pinned false; we don't send it.
198
+ # Enablement travels entirely through +environments+.
188
199
  SmplkitGeneratedClient::Audit::Forwarder.new(
189
200
  name: forwarder.name,
190
201
  description: forwarder.description,