vigiles 0.1.0.pre.beta3 → 0.1.0.pre.beta5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -1
- data/lib/vigiles/archive/extras.rb +4 -3
- data/lib/vigiles/archive/metadata.rb +3 -2
- data/lib/vigiles/archive/request.rb +18 -4
- data/lib/vigiles/archive.rb +15 -3
- data/lib/vigiles/constants.rb +7 -0
- data/lib/vigiles/middleware/record_conversation.rb +6 -22
- data/lib/vigiles/spec.rb +1 -1
- data/lib/vigiles/utilities/uri.rb +18 -0
- data/lib/vigiles/version.rb +2 -2
- data/lib/vigiles.rb +5 -1
- data/sorbet/rbi/gems/{activemodel@7.0.5.rbi → actioncable@7.1.3.3.rbi} +2 -2
- data/sorbet/rbi/gems/actionmailbox@7.1.3.3.rbi +8 -0
- data/sorbet/rbi/gems/{activerecord@7.0.5.rbi → actionmailer@7.1.3.3.rbi} +2 -2
- data/sorbet/rbi/gems/actionpack@7.1.3.3.rbi +20046 -0
- data/sorbet/rbi/gems/actiontext@7.1.3.3.rbi +8 -0
- data/sorbet/rbi/gems/actionview@7.1.3.3.rbi +15953 -0
- data/sorbet/rbi/gems/activejob@7.1.3.3.rbi +8 -0
- data/sorbet/rbi/gems/activemodel@7.1.3.3.rbi +6657 -0
- data/sorbet/rbi/gems/activerecord@7.1.3.3.rbi +41520 -0
- data/sorbet/rbi/gems/activestorage@7.1.3.3.rbi +8 -0
- data/sorbet/rbi/gems/activesupport@7.1.3.3.rbi +20570 -0
- data/sorbet/rbi/gems/base64@0.2.0.rbi +508 -0
- data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +77 -0
- data/sorbet/rbi/gems/builder@3.2.4.rbi +8 -0
- data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +8 -0
- data/sorbet/rbi/gems/crass@1.0.6.rbi +622 -0
- data/sorbet/rbi/gems/date@3.3.4.rbi +74 -0
- data/sorbet/rbi/gems/drb@2.2.1.rbi +1346 -0
- data/sorbet/rbi/gems/globalid@1.2.1.rbi +8 -0
- data/sorbet/rbi/gems/i18n@1.14.5.rbi +2358 -0
- data/sorbet/rbi/gems/io-console@0.7.2.rbi +8 -0
- data/sorbet/rbi/gems/loofah@2.22.0.rbi +1080 -0
- data/sorbet/rbi/gems/{i18n@1.14.1.rbi → mail@2.8.1.rbi} +2 -2
- data/sorbet/rbi/gems/marcel@1.0.4.rbi +8 -0
- data/sorbet/rbi/gems/mini_mime@1.1.5.rbi +8 -0
- data/sorbet/rbi/gems/mutex_m@0.2.0.rbi +93 -0
- data/sorbet/rbi/gems/net-imap@0.4.11.rbi +8 -0
- data/sorbet/rbi/gems/net-pop@0.1.2.rbi +8 -0
- data/sorbet/rbi/gems/net-protocol@0.2.2.rbi +291 -0
- data/sorbet/rbi/gems/net-smtp@0.5.0.rbi +8 -0
- data/sorbet/rbi/gems/nio4r@2.7.3.rbi +8 -0
- data/sorbet/rbi/gems/nokogiri@1.16.5.rbi +7310 -0
- data/sorbet/rbi/gems/psych@5.1.2.rbi +1768 -0
- data/sorbet/rbi/gems/rack-session@2.0.0.rbi +729 -0
- data/sorbet/rbi/gems/rack-test@2.1.0.rbi +749 -0
- data/sorbet/rbi/gems/rack@3.0.11.rbi +5195 -0
- data/sorbet/rbi/gems/rackup@2.1.0.rbi +406 -0
- data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +691 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +721 -0
- data/sorbet/rbi/gems/rails@7.1.3.3.rbi +8 -0
- data/sorbet/rbi/gems/railties@7.1.3.3.rbi +2167 -0
- data/sorbet/rbi/gems/rdoc@6.6.3.1.rbi +12715 -0
- data/sorbet/rbi/gems/reline@0.5.7.rbi +8 -0
- data/sorbet/rbi/gems/stringio@3.1.0.rbi +8 -0
- data/sorbet/rbi/gems/timeout@0.4.1.rbi +148 -0
- data/sorbet/rbi/gems/webrick@1.8.1.rbi +2606 -0
- data/sorbet/rbi/gems/websocket-driver@0.7.6.rbi +8 -0
- data/sorbet/rbi/gems/websocket-extensions@0.1.5.rbi +8 -0
- data/sorbet/rbi/gems/zeitwerk@2.6.13.rbi +1003 -0
- data/vigiles.gemspec +1 -1
- metadata +54 -7
- data/sorbet/rbi/gems/activesupport@7.0.5.rbi +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e4ea4b46169baf532079483c8827ee4d96f44165e3b5b1f4c021ac99a9a82bd
|
4
|
+
data.tar.gz: 8735c9877784c68115ea803aea9bad226d7926528208cbad19fef1f5d0d00b60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d8d94f910b17027a7db1776db0f1ec84b197a2a47e64de039cfab327af8d59cbfd7037ada8fa403f2c04cf4ef2f7697cb206da86529deab44d4f90bb7c92919
|
7
|
+
data.tar.gz: 0ed649f1d6fe5ef184d286eba622c7fbade046686bf56d7e8f0f35e06aad77820fa64c5434b64f68663537791e80ef5036c7ee228a79267463571e1319457107
|
data/.rubocop.yml
CHANGED
@@ -4,7 +4,7 @@ require:
|
|
4
4
|
- rubocop-sorbet
|
5
5
|
|
6
6
|
AllCops:
|
7
|
-
TargetRubyVersion:
|
7
|
+
TargetRubyVersion: 3.0
|
8
8
|
Exclude:
|
9
9
|
- "**/generators/**/*"
|
10
10
|
- "**/sorbet/**/*"
|
@@ -22,5 +22,14 @@ Style/AccessModifierDeclarations:
|
|
22
22
|
Enabled: true
|
23
23
|
EnforcedStyle: inline
|
24
24
|
|
25
|
+
Style/Documentation:
|
26
|
+
Enabled: false
|
27
|
+
|
25
28
|
Layout/LineLength:
|
26
29
|
Max: 120
|
30
|
+
|
31
|
+
Metrics/AbcSize:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Metrics/MethodLength:
|
35
|
+
Enabled: false
|
@@ -3,11 +3,12 @@
|
|
3
3
|
|
4
4
|
module Vigiles
|
5
5
|
module Archive
|
6
|
-
class Extras < T::Struct
|
7
|
-
const :request_env, T.untyped
|
6
|
+
class Extras < T::Struct
|
7
|
+
const :request_env, T::Hash[T.untyped, T.untyped]
|
8
8
|
|
9
|
+
sig { params(request_env: T::Hash[T.untyped, T.untyped]).returns(Extras) }
|
9
10
|
def self.from(request_env)
|
10
|
-
Extras.new(request_env:)
|
11
|
+
Extras.new(request_env: request_env)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -4,10 +4,11 @@
|
|
4
4
|
module Vigiles
|
5
5
|
module Archive
|
6
6
|
class Metadata < T::Struct
|
7
|
-
const :request_env, T.untyped
|
7
|
+
const :request_env, T::Hash[T.untyped, T.untyped]
|
8
8
|
|
9
|
+
sig { params(request_env: T::Hash[T.untyped, T.untyped]).returns(Metadata) }
|
9
10
|
def self.from(request_env)
|
10
|
-
Metadata.new(request_env:)
|
11
|
+
Metadata.new(request_env: request_env)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -8,6 +8,20 @@ module Vigiles
|
|
8
8
|
extend T::Sig
|
9
9
|
|
10
10
|
class Request < T::Struct
|
11
|
+
# raised when some request parameters are either bad/invalid
|
12
|
+
# or absent. for example, it is required the request url always
|
13
|
+
# be present, and have either http or https scheme.
|
14
|
+
class InvalidParameterError < StandardError
|
15
|
+
sig { returns(String) }
|
16
|
+
attr_reader :parameter
|
17
|
+
|
18
|
+
sig { params(parameter: String).void }
|
19
|
+
def initialize(parameter)
|
20
|
+
@parameter = parameter
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
11
25
|
const :content_type, String
|
12
26
|
const :http_method, Types::HttpMethod
|
13
27
|
const :user_agent, String
|
@@ -24,17 +38,17 @@ module Vigiles
|
|
24
38
|
sig { params(request: ActionDispatch::Request).returns(Request) }
|
25
39
|
def self.from(request)
|
26
40
|
Request.new(
|
27
|
-
content_type: request.content_type,
|
28
|
-
user_agent: request.user_agent,
|
41
|
+
content_type: request.content_type || (raise InvalidParameterError, "content_type"),
|
42
|
+
user_agent: request.user_agent || "unknown_user_agent",
|
29
43
|
timestamp: DateTime.now,
|
30
44
|
remote_ip: IPAddr.new(request.remote_ip),
|
31
45
|
protocol: request.protocol,
|
32
46
|
headers: {},
|
33
|
-
origin: request.origin || "
|
47
|
+
origin: request.origin || "unknown_origin_url",
|
34
48
|
payload: request.body.read,
|
35
49
|
http_method: Types::HttpMethod.deserialize(request.method),
|
36
50
|
path: request.path,
|
37
|
-
url: URI.
|
51
|
+
url: Utilities::URI.parse_into_http_or_https(request.url),
|
38
52
|
id: request.request_id
|
39
53
|
)
|
40
54
|
end
|
data/lib/vigiles/archive.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "action_dispatch"
|
5
|
-
|
6
4
|
module Vigiles
|
7
5
|
module Archive
|
8
6
|
extend T::Sig
|
@@ -10,6 +8,14 @@ module Vigiles
|
|
10
8
|
Types = Vigiles::Types
|
11
9
|
ContentType = Types::ContentType
|
12
10
|
|
11
|
+
class UnrecordableRequestError < StandardError
|
12
|
+
sig { params(reason: String).void }
|
13
|
+
def initialize(reason)
|
14
|
+
@reason = reason
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
sig { params(ad_response: ActionDispatch::Response).returns(T.nilable(Conversation)) }
|
14
20
|
def self.record_conversation(ad_response)
|
15
21
|
# preferring to call `response.request` instead of preparing a new
|
@@ -26,8 +32,10 @@ module Vigiles
|
|
26
32
|
case (content_type = request.content_type)
|
27
33
|
when ContentType::ApplicationJson.serialize then record_json_conversation(request:, response:, metadata:, extras:)
|
28
34
|
when ContentType::TextHtml.serialize then record_html_conversation(request:, response:, metadata:, extras:)
|
29
|
-
else record_conversation_with_unknown_content_type(request:)
|
35
|
+
else record_conversation_with_unknown_content_type(request:, response:, metadata:, extras:)
|
30
36
|
end
|
37
|
+
rescue Request::InvalidParameterError => e
|
38
|
+
raise UnrecordableRequestError, "#{e.parameter} considered invalid"
|
31
39
|
end
|
32
40
|
|
33
41
|
sig do
|
@@ -60,7 +68,11 @@ module Vigiles
|
|
60
68
|
)
|
61
69
|
rescue => e
|
62
70
|
end
|
71
|
+
|
72
|
+
sig { params(request: Request, response: Response, metadata: Metadata, extras: Extras).returns(T.nilable(Conversation)) }
|
63
73
|
private_class_method def self.record_html_conversation(request:, response:, metadata:, extras:); end
|
74
|
+
|
75
|
+
sig { params(request: Request, response: Response, metadata: Metadata, extras: Extras).returns(T.nilable(Conversation)) }
|
64
76
|
private_class_method def self.record_conversation_with_unknown_content_type(
|
65
77
|
request:,
|
66
78
|
response:,
|
@@ -1,26 +1,13 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "
|
5
|
-
|
4
|
+
require "logger"
|
6
5
|
module Vigiles
|
7
6
|
module Middleware
|
8
7
|
class RecordConversation
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
sig { returns(Options) }
|
13
|
-
def self.defaults
|
14
|
-
Options.new(
|
15
|
-
logger: Rails.logger
|
16
|
-
)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
sig { params(app: T.untyped, options: Options).void }
|
21
|
-
def initialize(app, options = Options.defaults)
|
22
|
-
@app = app
|
23
|
-
@logger = options.logger
|
8
|
+
sig { params(app: T.untyped).void }
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
24
11
|
end
|
25
12
|
|
26
13
|
sig { params(env: T.untyped).returns(T.untyped) }
|
@@ -30,15 +17,12 @@ module Vigiles
|
|
30
17
|
end
|
31
18
|
end
|
32
19
|
|
20
|
+
sig { params(blk: T.proc.returns(T.untyped)).returns(T.untyped) }
|
33
21
|
private def record_conversation(&blk)
|
34
22
|
rack_response = blk.call
|
35
23
|
_, _, body = rack_response
|
36
24
|
response = body.instance_variable_get(:@response)
|
37
|
-
unless response.nil?
|
38
|
-
convo = Vigiles.maybe_record_conversation(response)
|
39
|
-
@logger.info "conversation recorded: conversation_id=#{convo&.id}" if convo
|
40
|
-
end
|
41
|
-
|
25
|
+
Vigiles.maybe_record_conversation(response) unless response.nil?
|
42
26
|
rack_response
|
43
27
|
ensure
|
44
28
|
rack_response
|
data/lib/vigiles/spec.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vigiles
|
5
|
+
module Utilities
|
6
|
+
module URI
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(url: String).returns(T.any(::URI::HTTP, ::URI::HTTPS)) }
|
10
|
+
def self.parse_into_http_or_https(url)
|
11
|
+
parsed_uri = ::URI.parse(url)
|
12
|
+
raise unless parsed_uri.is_a?(::URI::HTTP) || parsed_uri.is_a?(::URI::HTTPS)
|
13
|
+
|
14
|
+
parsed_uri
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/vigiles/version.rb
CHANGED
data/lib/vigiles.rb
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
require "zeitwerk"
|
5
5
|
require "sorbet-runtime"
|
6
6
|
require_relative "core_ext"
|
7
|
+
require "action_dispatch"
|
7
8
|
|
8
9
|
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
10
|
+
loader.inflector.inflect("uri" => "URI")
|
9
11
|
loader.ignore("#{__dir__}/generators")
|
10
12
|
loader.ignore("#{__dir__}/core_ext.rb")
|
11
13
|
loader.ignore("#{__dir__}/core_ext")
|
@@ -19,11 +21,13 @@ module Vigiles
|
|
19
21
|
return unless should_record?(response)
|
20
22
|
|
21
23
|
Archive.record_conversation(response)
|
24
|
+
rescue Archive::UnrecordableRequestError
|
25
|
+
nil
|
22
26
|
end
|
23
27
|
|
24
28
|
sig { params(blk: T.untyped).void }
|
25
29
|
def self.configure(&blk)
|
26
|
-
default_spec = Vigiles::Spec.
|
30
|
+
default_spec = Vigiles::Spec.make_default_spec
|
27
31
|
blk.call(default_spec)
|
28
32
|
end
|
29
33
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# typed: true
|
2
2
|
|
3
3
|
# DO NOT EDIT MANUALLY
|
4
|
-
# This is an autogenerated file for types exported from the `
|
5
|
-
# Please instead update this file by running `bin/tapioca gem
|
4
|
+
# This is an autogenerated file for types exported from the `actioncable` gem.
|
5
|
+
# Please instead update this file by running `bin/tapioca gem actioncable`.
|
6
6
|
|
7
7
|
# THIS IS AN EMPTY RBI FILE.
|
8
8
|
# see https://github.com/Shopify/tapioca#manually-requiring-parts-of-a-gem
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
# DO NOT EDIT MANUALLY
|
4
|
+
# This is an autogenerated file for types exported from the `actionmailbox` gem.
|
5
|
+
# Please instead update this file by running `bin/tapioca gem actionmailbox`.
|
6
|
+
|
7
|
+
# THIS IS AN EMPTY RBI FILE.
|
8
|
+
# see https://github.com/Shopify/tapioca#manually-requiring-parts-of-a-gem
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# typed: true
|
2
2
|
|
3
3
|
# DO NOT EDIT MANUALLY
|
4
|
-
# This is an autogenerated file for types exported from the `
|
5
|
-
# Please instead update this file by running `bin/tapioca gem
|
4
|
+
# This is an autogenerated file for types exported from the `actionmailer` gem.
|
5
|
+
# Please instead update this file by running `bin/tapioca gem actionmailer`.
|
6
6
|
|
7
7
|
# THIS IS AN EMPTY RBI FILE.
|
8
8
|
# see https://github.com/Shopify/tapioca#manually-requiring-parts-of-a-gem
|