sofia 0.1.1 → 0.1.3
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/CLAUDE.md +53 -0
- data/README.md +67 -1
- data/lib/sofia/adapter/net_http.rb +28 -14
- data/lib/sofia/adapter/soren.rb +101 -0
- data/lib/sofia/adapter.rb +1 -0
- data/lib/sofia/client.rb +9 -4
- data/lib/sofia/defaults/timeouts.rb +12 -0
- data/lib/sofia/defaults.rb +8 -0
- data/lib/sofia/options.rb +29 -0
- data/lib/sofia/request.rb +18 -14
- data/lib/sofia/response.rb +2 -2
- data/lib/sofia/types/client/adapter.rb +43 -0
- data/lib/sofia/types/client/base_url.rb +35 -0
- data/lib/sofia/types/client/body.rb +62 -0
- data/lib/sofia/types/client/headers.rb +58 -0
- data/lib/sofia/types/client/options.rb +33 -0
- data/lib/sofia/types/client/params.rb +57 -0
- data/lib/sofia/types/client/path.rb +30 -0
- data/lib/sofia/types/client.rb +16 -0
- data/lib/sofia/types/options/timeout/base.rb +34 -0
- data/lib/sofia/types/options/timeout/connection.rb +12 -0
- data/lib/sofia/types/options/timeout/read.rb +12 -0
- data/lib/sofia/types/options/timeout/write.rb +12 -0
- data/lib/sofia/types/options/timeout.rb +15 -0
- data/lib/sofia/types/options.rb +10 -0
- data/lib/sofia/types.rb +2 -6
- data/lib/sofia/version.rb +1 -1
- data/lib/sofia.rb +7 -5
- data/sorbet/rbi/gems/soren@0.1.2.rbi +934 -0
- metadata +36 -8
- data/lib/sofia/types/adapter.rb +0 -39
- data/lib/sofia/types/base_url.rb +0 -33
- data/lib/sofia/types/body.rb +0 -60
- data/lib/sofia/types/headers.rb +0 -56
- data/lib/sofia/types/params.rb +0 -56
- data/lib/sofia/types/path.rb +0 -28
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Client
|
|
7
|
+
class Headers
|
|
8
|
+
|
|
9
|
+
#: (?untyped headers) -> void
|
|
10
|
+
def initialize(headers = {})
|
|
11
|
+
defaults = { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }
|
|
12
|
+
headers = validate_and_normalize(headers)
|
|
13
|
+
@headers = defaults.merge(headers) #: Hash[String, String]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#: (untyped key) -> void
|
|
17
|
+
def [](key)
|
|
18
|
+
@headers[key.to_s]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#: (untyped key, untyped value) -> void
|
|
22
|
+
def []=(key, value)
|
|
23
|
+
@headers[key.to_s] = value.to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#: -> Hash[String, String]
|
|
27
|
+
def to_h
|
|
28
|
+
@headers.dup
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#: () { ([String, String]) -> untyped } -> Hash[String, String]
|
|
32
|
+
def each(&block) # rubocop:disable Naming/BlockForwarding
|
|
33
|
+
@headers.each(&block) # rubocop:disable Naming/BlockForwarding
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
#: (untyped) -> Hash[String, String]
|
|
39
|
+
def validate_and_normalize(headers)
|
|
40
|
+
Kernel.raise Sofia::Error::ArgumentError, 'headers must be a Hash' unless headers.is_a?(Hash)
|
|
41
|
+
normalized = {}
|
|
42
|
+
|
|
43
|
+
headers.each do |key, value|
|
|
44
|
+
next if value.nil?
|
|
45
|
+
|
|
46
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
|
47
|
+
Kernel.raise Sofia::Error::ArgumentError, "invalid header value for #{key}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
normalized[key.to_s] = value.to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
normalized
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Client
|
|
7
|
+
class Options
|
|
8
|
+
|
|
9
|
+
#: Sofia::Options
|
|
10
|
+
attr_reader :value
|
|
11
|
+
|
|
12
|
+
#: (?untyped options) -> void
|
|
13
|
+
def initialize(options = nil)
|
|
14
|
+
@value = build(options) #: Sofia::Options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
#: (untyped) -> Sofia::Options
|
|
20
|
+
def build(options)
|
|
21
|
+
case options
|
|
22
|
+
when nil
|
|
23
|
+
Sofia::Options.new
|
|
24
|
+
when Hash
|
|
25
|
+
Sofia::Options.new(**options)
|
|
26
|
+
else
|
|
27
|
+
Kernel.raise Sofia::Error::ArgumentError, "options must be a Hash, got #{options.class}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Client
|
|
7
|
+
class Params
|
|
8
|
+
extend T::Sig
|
|
9
|
+
|
|
10
|
+
#: (?untyped params) -> void
|
|
11
|
+
def initialize(params = {}) # rubocop:disable Style/OptionHash
|
|
12
|
+
@params = validate_and_normalize(params || {}) #: Hash[String, String]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#: (untyped key) -> void
|
|
16
|
+
def [](key)
|
|
17
|
+
@params[key.to_s]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#: (untyped key, untyped value) -> void
|
|
21
|
+
def []=(key, value)
|
|
22
|
+
@params[key.to_s] = value.to_s
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#: -> Hash[String, String]
|
|
26
|
+
def to_h
|
|
27
|
+
@params.dup
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#: -> String
|
|
31
|
+
def to_s
|
|
32
|
+
URI.encode_www_form(@params)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
#: (untyped) -> Hash[String, String]
|
|
38
|
+
def validate_and_normalize(headers)
|
|
39
|
+
Kernel.raise Sofia::Error::ArgumentError, 'params must be a Hash' unless headers.is_a?(Hash)
|
|
40
|
+
normalized = {}
|
|
41
|
+
|
|
42
|
+
headers.each do |key, value|
|
|
43
|
+
next if value.nil?
|
|
44
|
+
|
|
45
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
|
46
|
+
Kernel.raise Sofia::Error::ArgumentError, "invalid param value for #{key}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
normalized[key.to_s] = value.to_s
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
normalized
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Client
|
|
7
|
+
class Path
|
|
8
|
+
|
|
9
|
+
#: (?untyped path) -> void
|
|
10
|
+
def initialize(path = '/')
|
|
11
|
+
@path = validate_and_normalize(path).freeze #: String
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#: -> String
|
|
15
|
+
def to_s
|
|
16
|
+
@path
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
#: (untyped) -> String
|
|
22
|
+
def validate_and_normalize(path)
|
|
23
|
+
Kernel.raise Sofia::Error::ArgumentError, 'path must be a String' unless path.is_a?(String)
|
|
24
|
+
|
|
25
|
+
path.start_with?('/') ? path : "/#{path}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Client; end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
require_relative 'client/adapter'
|
|
11
|
+
require_relative 'client/base_url'
|
|
12
|
+
require_relative 'client/headers'
|
|
13
|
+
require_relative 'client/body'
|
|
14
|
+
require_relative 'client/params'
|
|
15
|
+
require_relative 'client/path'
|
|
16
|
+
require_relative 'client/options'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Options
|
|
7
|
+
module Timeout
|
|
8
|
+
class Base
|
|
9
|
+
|
|
10
|
+
#: (untyped value) -> void
|
|
11
|
+
def initialize(value)
|
|
12
|
+
@value = validate_and_normalize(value) #: Float
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
#: -> Float
|
|
16
|
+
def to_f
|
|
17
|
+
@value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
#: (untyped) -> Float
|
|
23
|
+
def validate_and_normalize(value)
|
|
24
|
+
unless value.is_a?(Numeric) && value.to_f > 0
|
|
25
|
+
raise Sofia::Error::ArgumentError, "timeout must be a positive number, got #{value.inspect}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
value.to_f
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Sofia
|
|
5
|
+
module Types
|
|
6
|
+
module Options
|
|
7
|
+
module Timeout; end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require_relative 'timeout/base'
|
|
13
|
+
require_relative 'timeout/read'
|
|
14
|
+
require_relative 'timeout/write'
|
|
15
|
+
require_relative 'timeout/connection'
|
data/lib/sofia/types.rb
CHANGED
|
@@ -5,9 +5,5 @@ module Sofia
|
|
|
5
5
|
module Types; end
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
require_relative 'types/
|
|
9
|
-
require_relative 'types/
|
|
10
|
-
require_relative 'types/headers'
|
|
11
|
-
require_relative 'types/body'
|
|
12
|
-
require_relative 'types/params'
|
|
13
|
-
require_relative 'types/path'
|
|
8
|
+
require_relative 'types/client'
|
|
9
|
+
require_relative 'types/options'
|
data/lib/sofia/version.rb
CHANGED
data/lib/sofia.rb
CHANGED
|
@@ -8,18 +8,20 @@ require 'sorbet-runtime'
|
|
|
8
8
|
require 'byebug'
|
|
9
9
|
|
|
10
10
|
require_relative 'sofia/version'
|
|
11
|
+
require_relative 'sofia/error'
|
|
12
|
+
require_relative 'sofia/defaults'
|
|
13
|
+
require_relative 'sofia/types'
|
|
14
|
+
require_relative 'sofia/options'
|
|
11
15
|
require_relative 'sofia/request'
|
|
12
16
|
require_relative 'sofia/response'
|
|
13
17
|
require_relative 'sofia/adapter'
|
|
14
18
|
require_relative 'sofia/client'
|
|
15
|
-
require_relative 'sofia/error'
|
|
16
|
-
require_relative 'sofia/types'
|
|
17
19
|
|
|
18
20
|
module Sofia
|
|
19
21
|
class << self
|
|
20
|
-
#: (base_url: untyped, ?adapter: untyped) -> Sofia::Client
|
|
21
|
-
def new(base_url:, adapter: nil)
|
|
22
|
-
Client.new(base_url: base_url, adapter: adapter)
|
|
22
|
+
#: (base_url: untyped, ?adapter: untyped, ?options: untyped) -> Sofia::Client
|
|
23
|
+
def new(base_url:, adapter: nil, options: nil)
|
|
24
|
+
Client.new(base_url: base_url, adapter: adapter, options: options)
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|