scanii-ruby 1.1.0 → 1.2.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: '0418285adf3f56f3389b379b9eedadd5b281591cd2c7e62ad05092a8e8b22595'
4
- data.tar.gz: a61ce21d24bc78f557e09394868fc0c50b9fb2777b8649dce59b017a7d6a427c
3
+ metadata.gz: 2b4cc56c7cdba5d949e11dd004f7dbaa29ada9dab5e7b64173f5a523dc4f4e51
4
+ data.tar.gz: 37b10fb0ee6aa5dfbabf6b9c097fbf837f297fd557e27f0dc97e49278ed355d6
5
5
  SHA512:
6
- metadata.gz: 504165ee4f450fa8266675e1eb9d43d54a44e76547a5a8fe870865b4123c1563a4d9bf693df893855ecef9197288beb0e5da3425bf3a4524aa76cc1d02bbec25
7
- data.tar.gz: 897b47ed149ea571105dde92462e61d69f43fd496f20a50200dc64d0bce2e2ab7b52ade2837de7d5d6ac5a0f25f5de93f98f0d0ad5781f474b076d8c76c874e0
6
+ metadata.gz: 97c6569f83a40beb529c5d4a2189a57443201d17eafc9be2c75e693316ddf6d98e3306a9819d20346c6f573b0d3fbb182eea3493ad8269f4d8bdeef640b79096
7
+ data.tar.gz: 70cc50536847e7f83fce477098f6feb780ce6bf9ed3571d1ed92b0f8cd6b929eb5dd2fd2bd4cbdc5afc9d4b989f3df07ffdb86ae901e698e66de2884c95811c6
data/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to `scanii-ruby` are documented here. Versions follow [SemVer](https://semver.org).
4
4
 
5
+ ## [1.2.0] — v2.2 surface
6
+
7
+ ### New API
8
+
9
+ - `Scanii::Client#retrieve_trace(id)` → `Scanii::TraceResult` or `nil` — retrieves the
10
+ ordered processing event trace for a scan via `GET /files/{id}/trace`. Returns `nil` on 404
11
+ (no trace for that id). v2.2 preview surface; API shape may shift before marked stable.
12
+ - `Scanii::Client#process_from_url(location, callback: nil, metadata: nil)` →
13
+ `Scanii::ProcessingResult` — submits a URL for synchronous scanning via `POST /files` with
14
+ `location` as a multipart/form-data field. Distinct from `fetch`, which submits to
15
+ `/files/fetch` for asynchronous server-side fetching. `location` must be a String URL.
16
+ v2.2 preview surface.
17
+ - `Scanii::TraceResult` — new result class with `id`, `events`, `request_id`, `host_id`,
18
+ `raw_response`.
19
+ - `Scanii::TraceEvent` — new model with `timestamp` (String) and `message` (String).
20
+
21
+ ### Deprecations
22
+
23
+ - `Scanii::ProcessingResult#error` — deprecated. The server never populates this field on
24
+ successful responses; errors arrive as non-2xx HTTP responses that raise `Scanii::Error`
25
+ subclasses. The field still exists and emits a runtime `warn` on access. Will be removed
26
+ in a future major version.
27
+
5
28
  ## 1.1.0 — Streaming standardization
6
29
 
7
30
  Adds stream-based `process` and `process_async` methods, aligning scanii-ruby with the
data/README.md CHANGED
@@ -60,8 +60,10 @@ puts "findings: #{result.findings.inspect}"
60
60
  | `process_file(path, metadata:, callback:)` | `POST /files` | `Scanii::ProcessingResult` |
61
61
  | `process_async(io, filename:, content_type:, metadata:, callback:)` | `POST /files/async` | `Scanii::PendingResult` |
62
62
  | `process_async_file(path, metadata:, callback:)` | `POST /files/async` | `Scanii::PendingResult` |
63
+ | `process_from_url(location, callback:, metadata:)` | `POST /files` | `Scanii::ProcessingResult` (v2.2 preview) |
63
64
  | `fetch(url, metadata:, callback:)` | `POST /files/fetch` | `Scanii::PendingResult` |
64
65
  | `retrieve(id)` | `GET /files/{id}` | `Scanii::ProcessingResult` |
66
+ | `retrieve_trace(id)` | `GET /files/{id}/trace` | `Scanii::TraceResult` or `nil` (v2.2 preview) |
65
67
  | `ping` | `GET /ping` | `true` |
66
68
  | `create_auth_token(timeout_seconds)` | `POST /auth/tokens` | `Scanii::AuthToken` |
67
69
  | `retrieve_auth_token(id)` | `GET /auth/tokens/{id}` | `Scanii::AuthToken` |
data/lib/scanii/client.rb CHANGED
@@ -184,6 +184,70 @@ module Scanii
184
184
  ProcessingResult.from_response(resp_body, headers)
185
185
  end
186
186
 
187
+ # Retrieve the processing event trace for a previously submitted scan.
188
+ #
189
+ # Returns nil when no trace exists for the given id (HTTP 404).
190
+ #
191
+ # This is a v2.2 preview surface; the API shape may shift before it is
192
+ # marked stable.
193
+ #
194
+ # @param id [String] processing id returned by process or process_file
195
+ # @see https://scanii.github.io/openapi/v22/ GET /files/{id}/trace
196
+ # @return [Scanii::TraceResult, nil]
197
+ def retrieve_trace(id)
198
+ raise ArgumentError, "id must not be empty" if id.nil? || id.empty?
199
+
200
+ status, resp_body, headers = request("GET", "/files/#{url_encode(id)}/trace")
201
+ return nil if status == 404
202
+
203
+ raise_for_status(status, resp_body, headers) unless status == 200
204
+ TraceResult.from_response(resp_body, headers)
205
+ end
206
+
207
+ # Submit a remote URL for synchronous scanning.
208
+ #
209
+ # Sends the URL as a +location+ field in a multipart/form-data POST to
210
+ # +/files+. The Scanii server fetches and scans the URL synchronously and
211
+ # returns a ProcessingResult. This is distinct from {#fetch}, which submits
212
+ # to +/files/fetch+ for asynchronous server-side fetching.
213
+ #
214
+ # +location+ must be a String URL. This matches the existing {#fetch}
215
+ # String-URL convention and the Java reference (processFromUrl(String)).
216
+ #
217
+ # This is a v2.2 preview surface; the API shape may shift before it is
218
+ # marked stable.
219
+ #
220
+ # @param location [String] URL of the content to scan
221
+ # @param callback [String, nil] URL to POST the result to on completion
222
+ # @param metadata [Hash{String=>String}, nil] arbitrary key/value pairs attached to the result
223
+ # @see https://scanii.github.io/openapi/v22/ POST /files
224
+ # @return [Scanii::ProcessingResult]
225
+ def process_from_url(location, callback: nil, metadata: nil)
226
+ raise ArgumentError, "location must not be empty" if location.nil? || location.to_s.empty?
227
+
228
+ fields = build_text_fields(metadata, callback)
229
+ fields["location"] = location.to_s
230
+
231
+ boundary = Multipart.make_boundary
232
+ body = String.new(encoding: Encoding::BINARY)
233
+ fields.each do |name, value|
234
+ body << "--#{boundary}\r\n".b
235
+ body << "Content-Disposition: form-data; name=\"#{name}\"\r\n".b
236
+ body << "Content-Type: text/plain; charset=UTF-8\r\n\r\n".b
237
+ body << value.to_s.b
238
+ body << "\r\n".b
239
+ end
240
+ body << "--#{boundary}--\r\n".b
241
+
242
+ status, resp_body, headers = post(
243
+ "/files",
244
+ body: body,
245
+ content_type: Multipart.make_content_type(boundary)
246
+ )
247
+ raise_for_status(status, resp_body, headers) unless status == 201
248
+ ProcessingResult.from_response(resp_body, headers)
249
+ end
250
+
187
251
  # Verify that the configured credentials reach the API.
188
252
  #
189
253
  # @see https://scanii.github.io/openapi/v22/ GET /ping
@@ -9,7 +9,7 @@ module Scanii
9
9
  # @see https://scanii.github.io/openapi/v22/
10
10
  class ProcessingResult
11
11
  attr_reader :id, :findings, :checksum, :content_length, :content_type,
12
- :metadata, :creation_date, :error,
12
+ :metadata, :creation_date,
13
13
  :request_id, :host_id, :resource_location, :raw_response
14
14
 
15
15
  def initialize(id:, findings:, checksum:, content_length:, content_type:,
@@ -22,13 +22,23 @@ module Scanii
22
22
  @content_type = content_type
23
23
  @metadata = metadata
24
24
  @creation_date = creation_date
25
- @error = error
25
+ @_error = error
26
26
  @request_id = request_id
27
27
  @host_id = host_id
28
28
  @resource_location = resource_location
29
29
  @raw_response = raw_response
30
30
  end
31
31
 
32
+ # @deprecated The server never populates this field on successful responses;
33
+ # errors arrive as non-2xx HTTP responses that raise Scanii::Error
34
+ # subclasses. Will be removed in a future major version.
35
+ def error
36
+ warn "[DEPRECATION] `Scanii::ProcessingResult#error` is deprecated; " \
37
+ "rescue Scanii::Error (and its subclasses) to handle server-side errors. " \
38
+ "Will be removed in a future major version."
39
+ @_error
40
+ end
41
+
32
42
  def self.from_response(body, headers)
33
43
  json = body.nil? || body.empty? ? {} : JSON.parse(body)
34
44
 
@@ -0,0 +1,20 @@
1
+ module Scanii
2
+ # A single processing event in a {Scanii::TraceResult}.
3
+ #
4
+ # @see https://scanii.github.io/openapi/v22/
5
+ class TraceEvent
6
+ attr_reader :timestamp, :message
7
+
8
+ def initialize(timestamp:, message:)
9
+ @timestamp = timestamp
10
+ @message = message
11
+ end
12
+
13
+ def self.from_hash(hash)
14
+ new(
15
+ timestamp: hash["timestamp"]&.to_s,
16
+ message: hash["message"]&.to_s
17
+ )
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ require "json"
2
+
3
+ module Scanii
4
+ # Result of Client#retrieve_trace — ordered processing events for a scan.
5
+ #
6
+ # This is a v2.2 preview surface; the API shape may shift before it is
7
+ # marked stable.
8
+ #
9
+ # @see https://scanii.github.io/openapi/v22/
10
+ class TraceResult
11
+ attr_reader :id, :events, :request_id, :host_id, :raw_response
12
+
13
+ def initialize(id:, events:, request_id:, host_id:, raw_response:)
14
+ @id = id
15
+ @events = events
16
+ @request_id = request_id
17
+ @host_id = host_id
18
+ @raw_response = raw_response
19
+ end
20
+
21
+ def self.from_response(body, headers)
22
+ json = body.nil? || body.empty? ? {} : JSON.parse(body)
23
+
24
+ new(
25
+ id: (json["id"] || "").to_s,
26
+ events: Array(json["events"]).map { |e| TraceEvent.from_hash(e) },
27
+ request_id: headers["x-scanii-request-id"],
28
+ host_id: headers["x-scanii-host-id"],
29
+ raw_response: body
30
+ )
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Scanii
2
- VERSION = "1.1.0".freeze
2
+ VERSION = "1.2.0".freeze
3
3
  end
data/lib/scanii.rb CHANGED
@@ -3,6 +3,8 @@ require_relative "scanii/error"
3
3
  require_relative "scanii/processing_result"
4
4
  require_relative "scanii/pending_result"
5
5
  require_relative "scanii/auth_token"
6
+ require_relative "scanii/trace_event"
7
+ require_relative "scanii/trace_result"
6
8
  require_relative "scanii/multipart"
7
9
  require_relative "scanii/client"
8
10
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scanii-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scanii
@@ -80,6 +80,8 @@ files:
80
80
  - lib/scanii/multipart.rb
81
81
  - lib/scanii/pending_result.rb
82
82
  - lib/scanii/processing_result.rb
83
+ - lib/scanii/trace_event.rb
84
+ - lib/scanii/trace_result.rb
83
85
  - lib/scanii/version.rb
84
86
  homepage: https://github.com/scanii/scanii-ruby
85
87
  licenses: