vigiles 0.1.0.pre.beta6 → 0.1.0.pre.beta8

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: 6ad47542ac3fa029cef8be2b99b104eb7995abf67765c8e0582426249f2d5a5a
4
- data.tar.gz: a468738d5ef0ad815be016420198ef939b254997509b25228f5b3779fa51976f
3
+ metadata.gz: 9ae2f2c7a8b3a0642d0fb228264821c882b9b98cf7a59380dcf139e1a514221c
4
+ data.tar.gz: 7ca651c0579f55907094ade6d43825cae72627fef6c8e995fd621d7f94e9acc4
5
5
  SHA512:
6
- metadata.gz: df8d3f3c5361e26b23b6a8cce014c4c55f3b15cc09f754a5ed3c34f15250360e09d6a0964ed23df5b1eb81cb87bec575198f71237fd24e1ce5f3ff201b279dc6
7
- data.tar.gz: fe0759a9e54c564ee235f421dbd8c7d8cfe34378777c1c3737fb29fa152a7f277c4a94808e138ec4fb61c0ef7a619bed8b60a9d14d3059299772a3ef4c2dbcda
6
+ metadata.gz: a942ca1c61aefdb02f843b7d3defd046ebce9935b47d406e8193c2c54b7befd360b19f974618f24f42c23278e8c313be513d25b68fece32985d2272f504b8c2e
7
+ data.tar.gz: 2a70d2be56a5c86fa4f30f881b6b9002e6967cfe6cd04339f1bb4f70f1a6f8bd28b6ae34281a19b5504ad82a594fa8b0660591ff0ab28e9ad3fdd94214c26d78
@@ -37,7 +37,7 @@ module Vigiles
37
37
 
38
38
  sig { params(request: ActionDispatch::Request).returns(Request) }
39
39
  def self.from(request)
40
- preferred_headers = Vigiles.specification.request_headers
40
+ preferred_headers = Vigiles.spec.request_headers
41
41
  available_headers = request.original_headers
42
42
  recorded_headers = (available_headers if preferred_headers.empty?)
43
43
  recorded_headers ||= preferred_headers.to_h { |h| [h, available_headers[h]] }
@@ -16,14 +16,17 @@ module Vigiles
16
16
  when Array
17
17
  return { body: :empty_no_content } if body.empty?
18
18
 
19
- { body: :not_empty_handle_later }
19
+ { __false_body: :not_empty_handle_later }
20
20
  when Rack::BodyProxy
21
21
  body_proxy = body
22
22
  body_proxy = body_proxy.instance_variable_get(:@body) until body_proxy.is_a?(Array)
23
- JSON.parse(body_proxy[0])
23
+ begin
24
+ JSON.parse(body_proxy[0])
25
+ rescue StandardError
26
+ { __false_body: body_proxy[0] }
27
+ end
24
28
  else
25
- debugger
26
- { body: :unknown_response_payload_type }
29
+ { __false_body: :unknown_response_payload_type }
27
30
  end
28
31
  end
29
32
 
@@ -18,23 +18,14 @@ module Vigiles
18
18
 
19
19
  sig { params(req: ActionDispatch::Request, res: Rack::Response).returns(T.nilable(Conversation)) }
20
20
  def self.record_conversation(req:, res:)
21
- # preferring to call `response.request` instead of preparing a new
22
- # request (via `ActionDispatch::Request.new(env)` and passing it
23
- # as an argument to this method because we can always recover the
24
- # specific request that elicited a given response, according to
25
- # https://github.com/rails/rails/blob/cacb8475a9d4373c0db437e7be4905685f03cefa/actionpack/lib/action_dispatch/http/response.rb#L53
26
- response = Response.from(res)
27
- metadata = Metadata.from(req.env)
28
- request = Request.from(req)
29
- extras = Extras.from(req.env)
30
-
31
- case (content_type = request.content_type)
32
- when ContentType::ApplicationJson.serialize then record_json_conversation(request:, response:, metadata:, extras:)
33
- when ContentType::TextHtml.serialize then record_html_conversation(request:, response:, metadata:, extras:)
34
- else record_conversation_with_unknown_content_type(request:, response:, metadata:, extras:)
21
+ content_type = req.content_type
22
+ if (recorder = Vigiles.spec.recorders[content_type]).nil?
23
+ raise \
24
+ UnrecordableRequestError,
25
+ "no recorder configured for content type: #{content_type}"
35
26
  end
36
- rescue Request::InvalidParameterError => e
37
- raise UnrecordableRequestError, "#{e.parameter} considered invalid"
27
+
28
+ recorder.record(req:, res:)
38
29
  end
39
30
 
40
31
  sig do
@@ -3,9 +3,24 @@
3
3
 
4
4
  module Vigiles
5
5
  class ConversationRecorder
6
+ class MisconfiguredRecorderError < StandardError
7
+ sig { returns(String) }
8
+ attr_reader :expected
9
+
10
+ sig { returns(String) }
11
+ attr_reader :actual
12
+
13
+ sig { params(expected: String, actual: String).void }
14
+ def initialize(expected:, actual:)
15
+ @expected = expected
16
+ @actual = actual
17
+ super
18
+ end
19
+ end
20
+
6
21
  abstract!
7
22
 
8
- sig { abstract.params(response: ActionDispatch::Response).returns(Archive::Conversation) }
9
- def record(response); end
23
+ sig { abstract.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
24
+ def record(req:, res:); end
10
25
  end
11
26
  end
@@ -6,8 +6,45 @@ module Vigiles
6
6
  class ApplicationJson < ConversationRecorder
7
7
  include Singleton
8
8
 
9
- sig { override.params(_response: ActionDispatch::Response).returns(Archive::Conversation) }
10
- def record(_response) = Archive::Conversation.new
9
+ ConversationRecorder = Vigiles::ConversationRecorder
10
+ ContentType = Vigiles::Types::ContentType
11
+ Conversation = Vigiles::Archive::Conversation
12
+ Response = Vigiles::Archive::Response
13
+ Metadata = Vigiles::Archive::Metadata
14
+ Request = Vigiles::Archive::Request
15
+ Extras = Vigiles::Archive::Extras
16
+
17
+ sig { override.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
18
+ def record(req:, res:)
19
+ unless req.content_type == ContentType::ApplicationJson.serialize
20
+ raise ConversationRecorder::MisconfiguredRecorderError.new(
21
+ expected: ContentType::ApplicationJson.serialize,
22
+ actual: req.content_type
23
+ )
24
+ end
25
+
26
+ response = Response.from(res)
27
+ request = Request.from(req)
28
+
29
+ Conversation.create!(
30
+ request_content_type: request.content_type,
31
+ request_user_agent: request.user_agent,
32
+ request_timestamp: request.timestamp,
33
+ request_remote_ip: request.remote_ip,
34
+ request_protocol: request.protocol,
35
+ request_headers: request.headers,
36
+ request_origin: request.origin,
37
+ request_payload: request.payload,
38
+ request_method: request.http_method.serialize,
39
+ request_path: request.path,
40
+ request_url: request.url,
41
+ request_id: request.id,
42
+ response_content_type: response.content_type,
43
+ response_headers: response.headers,
44
+ response_payload: response.payload,
45
+ response_status: response.status
46
+ )
47
+ end
11
48
  end
12
49
  end
13
50
  end
@@ -4,8 +4,10 @@
4
4
  module Vigiles
5
5
  module ConversationRecorders
6
6
  class Unknown < ConversationRecorder
7
- sig { override.params(_response: ActionDispatch::Response).returns(Archive::Conversation) }
8
- def record(_response) = Archive::Conversation.new
7
+ include Singleton
8
+
9
+ sig { override.params(req: ActionDispatch::Request, res: Rack::Response).returns(Archive::Conversation) }
10
+ def record(req:, res:) = Archive::Conversation.new
9
11
  end
10
12
  end
11
13
  end
data/lib/vigiles/spec.rb CHANGED
@@ -3,16 +3,16 @@
3
3
 
4
4
  module Vigiles
5
5
  class Spec < T::Struct
6
- const :content_type_recorders, T::Hash[String, ConversationRecorder]
7
6
  const :request_content_types, T::Set[String]
8
7
  const :request_headers, T::Set[String]
8
+ const :recorders, T::Hash[String, ConversationRecorder]
9
9
 
10
10
  sig { returns(Spec) }
11
11
  def self.make_default_spec
12
12
  Spec.new(
13
- content_type_recorders: Constants::DEFAULT_CONTENT_TYPE_RECORDERS,
14
13
  request_content_types: Constants::DEFAULT_CONTENT_TYPES,
15
- request_headers: Set[]
14
+ request_headers: Set[].freeze,
15
+ recorders: Constants::DEFAULT_CONTENT_TYPE_RECORDERS
16
16
  )
17
17
  end
18
18
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Vigiles
5
- VERSION = "0.1.0-beta6"
5
+ VERSION = "0.1.0-beta8"
6
6
  end
data/lib/vigiles.rb CHANGED
@@ -17,16 +17,16 @@ module Vigiles
17
17
  extend T::Sig
18
18
 
19
19
  sig { returns(Vigiles::Spec) }
20
- def self.specification
21
- @specification ||= T.let(
20
+ def self.spec
21
+ @spec ||= T.let(
22
22
  Vigiles::Spec.make_default_spec,
23
23
  T.nilable(Vigiles::Spec)
24
24
  )
25
25
  end
26
26
 
27
27
  sig { params(spec: Vigiles::Spec).returns(Vigiles::Spec) }
28
- def self.specification=(spec)
29
- @specification = spec
28
+ def self.spec=(spec)
29
+ @spec = spec
30
30
  end
31
31
 
32
32
  sig { params(req: ActionDispatch::Request, res: Rack::Response).returns(T.nilable(Archive::Conversation)) }
@@ -40,9 +40,9 @@ module Vigiles
40
40
 
41
41
  sig { params(blk: T.untyped).void }
42
42
  def self.configure(&blk)
43
- blk.call(specification)
43
+ blk.call(spec)
44
44
 
45
- # TODO(yaw, 2024-06-15): ensure that the specification is valid.
45
+ # TODO(yaw, 2024-06-15): ensure that the spec is valid.
46
46
  # ensure that for every content type a recorder is configured. otherwise
47
47
  # assign the general recorder for unknown content types.
48
48
  end
@@ -3,10 +3,10 @@
3
3
 
4
4
  require "action_dispatch"
5
5
  require "active_record"
6
+ require "logger"
6
7
  require "minitest/autorun"
7
8
  require "rails/generators"
8
9
  require "rails/generators/active_record"
9
10
  require "securerandom"
10
11
  require "sorbet-runtime"
11
- require "uri"
12
12
  require "zeitwerk"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vigiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.beta6
4
+ version: 0.1.0.pre.beta8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaw Boakye