ur 0.0.1 → 0.0.2

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: '09cd35887d4f337c01a55526c85dec4d0473ed24532d920960890cccc44f3f52'
4
- data.tar.gz: e6cb70fe2d62dd42864c6fd6b2b6cf7c9ebf3f0c73744e0fa8a952618e1d8b1e
3
+ metadata.gz: 85e941c9b4dad6807b7635acc90b762e4f096f38f8f981511be120e42effc7f9
4
+ data.tar.gz: cbca689430e05b3865b8572dacbc114201c4af217b0e893fade40ae2a74f3b12
5
5
  SHA512:
6
- metadata.gz: 3e1b5884244f923e22e6570d3e87ce7b3d70771987845bff06da886bb86ed9d29623cbdbf6c55ed943b53529e1506d53f5b995704de177a279c566e8770986f0
7
- data.tar.gz: 040554fff56b914de9343fb4abd7e5175557224c34632385efaa5794125587f1ea4ae31f5cf8c9b761d20d8b881a320abcee4ebd49cd2614f25680dcce534d09
6
+ metadata.gz: e45319855396792763e515a96d21ad3e56475461c9b8733b4d0dfb97dee9a2e3efac7107b0f58a510003ab70a17e64c367dde594ea8d0e3acd5a771be6a47044
7
+ data.tar.gz: b7d0f97850df360137870edefe21f321b9f919f84d1ec9be65c45e30461297b6e725d949e9051de6c7f87bd3d9bef25be1cb7479fc20356f8dfb2fd7cf79d58f
@@ -1,3 +1,12 @@
1
+ # v0.0.2
2
+
3
+ - module SubUr common to Ur::Request, Response, Processing
4
+ - Ur methods prefixed with sub-ur names delegate, e.g. Ur#request_uri delegates to ur.request.uri
5
+ - Ur::Response#success?, #client_error?, #server_error?
6
+ - Ur::Request and Ur::Response content_type attributes and media_type
7
+ - Ur::Faraday::YieldUr middleware
8
+ - bugfixes and refactoring
9
+
1
10
  # v0.0.1
2
11
 
3
12
  - Ur, Ur::Request, Ur::Response, Ur::Processing
data/lib/ur.rb CHANGED
@@ -43,10 +43,12 @@ Ur = JSI.class_for_schema({
43
43
  class Ur
44
44
  VERSION = UR_VERSION
45
45
 
46
+ autoload :SubUr, 'ur/sub_ur'
46
47
  autoload :RequestAndResponse, 'ur/request_and_response'
47
48
  autoload :Middleware, 'ur/middleware'
48
49
  autoload :FaradayMiddleware, 'ur/middleware'
49
50
  autoload :RackMiddleware, 'ur/middleware'
51
+ autoload :Faraday, 'ur/faraday'
50
52
 
51
53
  Request = JSI.class_for_schema(self.schema['properties']['request'])
52
54
  Response = JSI.class_for_schema(self.schema['properties']['response'])
@@ -55,6 +57,8 @@ class Ur
55
57
  require 'ur/response'
56
58
  require 'ur/processing'
57
59
 
60
+ autoload :ContentTypeAttrs, 'ur/content_type_attrs'
61
+
58
62
  class << self
59
63
  def from_rack_request(request_env)
60
64
  if request_env.is_a?(Rack::Request)
@@ -65,9 +69,8 @@ class Ur
65
69
  env = request_env
66
70
  end
67
71
 
68
- Ur.new({}).tap do |ur|
72
+ new({'bound' => 'inbound'}).tap do |ur|
69
73
  ur.processing.begin!
70
- ur.bound = 'inbound'
71
74
  ur.request['method'] = rack_request.request_method
72
75
  ur.request.headers = env.map do |(key, value)|
73
76
  http_match = key.match(/\AHTTP_/)
@@ -95,9 +98,8 @@ class Ur
95
98
  end
96
99
 
97
100
  def from_faraday_request(request_env, logger: nil)
98
- Ur.new({}).tap do |ur|
101
+ new({'bound' => 'outbound'}).tap do |ur|
99
102
  ur.processing.begin!
100
- ur.bound = 'outbound'
101
103
  ur.request['method'] = request_env[:method].to_s
102
104
  ur.request.headers = request_env[:request_headers]
103
105
  ur.request.uri = request_env[:url].normalize.to_s
@@ -106,8 +108,9 @@ class Ur
106
108
  end
107
109
  end
108
110
 
109
- def initialize(ur = {}, *a, &b)
110
- super(ur, *a, &b)
111
+ def initialize(ur = {}, **opt, &b)
112
+ ur = JSI::JSON::Node.new_doc(ur) unless ur.is_a?(JSI::JSON::Node)
113
+ super(ur, **opt, &b)
111
114
  unless instance.respond_to?(:to_hash)
112
115
  raise(TypeError, "expected hash argument. got: #{ur.pretty_inspect.chomp}")
113
116
  end
@@ -147,4 +150,18 @@ class Ur
147
150
  yield(response_env)
148
151
  end
149
152
  end
153
+
154
+ # define delegator sort of methods for nested property names, eg.
155
+ # ur.request_uri
156
+ # this makes it easier to use Symbol#to_proc, eg urs.map(&:request_uri)
157
+ # instead of urs.map(&:request).map(&:uri)
158
+ schema['properties'].each do |property_name, property_schema|
159
+ if property_schema['type'] == 'object' && property_schema['properties']
160
+ property_schema['properties'].each_key do |property_property_name|
161
+ define_method("#{property_name}_#{property_property_name}") do
162
+ self[property_name][property_property_name]
163
+ end
164
+ end
165
+ end
166
+ end
150
167
  end
@@ -0,0 +1,83 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ # parses attributes out of content type header
5
+ class ContentTypeAttrs
6
+ def initialize(content_type)
7
+ raise(ArgumentError) unless content_type.nil? || content_type.respond_to?(:to_str)
8
+ content_type = content_type.to_str if content_type
9
+ @media_type = (content_type.split(/\s*[;]\s*/, 2).first if content_type)
10
+ @media_type.strip! if @media_type
11
+ @content_type = content_type
12
+ @parsed = false
13
+ @attributes = Hash.new { |h,k| h[k] = [] }
14
+ catch(:unparseable) do
15
+ throw(:unparseable) unless content_type
16
+ uri_parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
17
+ scanner = StringScanner.new(content_type)
18
+ scanner.scan(/.*;\s*/) || throw(:unparseable)
19
+ while scanner.scan(/(\w+)=("?)([^"]*)("?)\s*(,?)\s*/)
20
+ key = scanner[1]
21
+ quote1 = scanner[2]
22
+ value = scanner[3]
23
+ quote2 = scanner[4]
24
+ comma_follows = !scanner[5].empty?
25
+ throw(:unparseable) unless quote1 == quote2
26
+ throw(:unparseable) if !comma_follows && !scanner.eos?
27
+ @attributes[uri_parser.unescape(key)] << uri_parser.unescape(value)
28
+ end
29
+ throw(:unparseable) unless scanner.eos?
30
+ @parsed = true
31
+ end
32
+ end
33
+
34
+ attr_reader :content_type, :media_type
35
+
36
+ def parsed?
37
+ @parsed
38
+ end
39
+
40
+ def [](key)
41
+ @attributes[key]
42
+ end
43
+
44
+ def text?
45
+ # ordered hash by priority mapping types to binary or text
46
+ # regexps will have \A and \z added
47
+ types = {
48
+ %r(image/.*) => :binary,
49
+ %r(audio/.*) => :binary,
50
+ %r(video/.*) => :binary,
51
+ %r(model/.*) => :binary,
52
+ %r(text/.*) => :text,
53
+ %r(message/.*) => :text,
54
+ %r(application/(.+\+)?json) => :text,
55
+ %r(application/(.+\+)?xml) => :text,
56
+ %r(model/(.+\+)?xml) => :text,
57
+ 'application/x-www-form-urlencoded' => :text,
58
+ 'application/javascript' => :text,
59
+ 'application/ecmascript' => :text,
60
+ 'application/octet-stream' => :binary,
61
+ 'application/ogg' => :binary,
62
+ 'application/pdf' => :binary,
63
+ 'application/postscript' => :binary,
64
+ 'application/zip' => :binary,
65
+ 'application/gzip' => :binary,
66
+ 'application/vnd.apple.pkpass' => :binary,
67
+ }
68
+ types.each do |match, type|
69
+ matched = match.is_a?(Regexp) ? media_type =~ %r(\A#{match.source}\z) : media_type == match
70
+ if matched
71
+ return type == :text
72
+ end
73
+ end
74
+ # fallback (unknown or not given) assume that unknown content types are binary but omitted
75
+ # content-type means text
76
+ if content_type && content_type =~ /\S/
77
+ return false
78
+ else
79
+ return true
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ require 'faraday'
2
+
3
+ class Ur
4
+ module Faraday
5
+ autoload :YieldUr, 'ur/faraday/yield_ur'
6
+ end
7
+ end
8
+
9
+ Faraday::Response.register_middleware(:yield_ur => proc { Ur::Faraday::YieldUr })
@@ -0,0 +1,19 @@
1
+ class Ur
2
+ module Faraday
3
+ class YieldUr < ::Faraday::Middleware
4
+ def initialize(app, options = {}, &block)
5
+ @app = app
6
+ @options = options
7
+ @yield_to = block
8
+ end
9
+
10
+ def call(request_env)
11
+ ur = Scorpio::Ur.from_faraday_request(request_env)
12
+ ur.logger = @options[:logger]
13
+ ur.faraday_on_complete(@app, request_env) do |response_env|
14
+ @yield_to.call(ur)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,6 +2,8 @@ require 'ur' unless Object.const_defined?(:Ur)
2
2
 
3
3
  class Ur
4
4
  class Processing
5
+ include SubUr
6
+
5
7
  def began_at
6
8
  began_at_s ? Time.parse(began_at_s) : nil
7
9
  end
@@ -3,6 +3,7 @@ require 'ur' unless Object.const_defined?(:Ur)
3
3
  class Ur
4
4
  class Request
5
5
  include RequestAndResponse
6
+ include SubUr
6
7
 
7
8
  def addressable_uri
8
9
  uri ? Addressable::URI.parse(uri) : nil
@@ -19,5 +19,21 @@ class Ur
19
19
  end
20
20
  end
21
21
  include FaradayEntity
22
+
23
+ def content_type_attrs
24
+ return @content_type_attrs if instance_variable_defined?(:@content_type_attrs)
25
+ @content_type_attrs = ContentTypeAttrs.new(content_type)
26
+ end
27
+
28
+ def content_type
29
+ headers.each do |k, v|
30
+ return v if k =~ /\Acontent[-_]type\z/i
31
+ end
32
+ nil
33
+ end
34
+
35
+ def media_type
36
+ content_type_attrs.media_type
37
+ end
22
38
  end
23
39
  end
@@ -3,5 +3,18 @@ require 'ur' unless Object.const_defined?(:Ur)
3
3
  class Ur
4
4
  class Response
5
5
  include RequestAndResponse
6
+ include SubUr
7
+
8
+ def success?
9
+ (200..299).include?(status)
10
+ end
11
+
12
+ def client_error?
13
+ (400..499).include?(status)
14
+ end
15
+
16
+ def server_error?
17
+ (500..599).include?(status)
18
+ end
6
19
  end
7
20
  end
@@ -0,0 +1,9 @@
1
+ require 'ur' unless Object.const_defined?(:Ur)
2
+
3
+ class Ur
4
+ module SubUr
5
+ def ur
6
+ parents.detect { |p| p.is_a?(::Ur) }
7
+ end
8
+ end
9
+ end
@@ -1 +1 @@
1
- UR_VERSION = "0.0.1"
1
+ UR_VERSION = "0.0.2"
data/ur.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
- spec.add_dependency "jsi", "~> 0.0.2"
31
+ spec.add_dependency "jsi", "~> 0.0.3"
32
32
  spec.add_dependency "addressable", "~> 2.0"
33
33
  spec.add_development_dependency "rack"
34
34
  spec.add_development_dependency "rack-test"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ur
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-09-27 00:00:00.000000000 Z
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jsi
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.2
19
+ version: 0.0.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.2
26
+ version: 0.0.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -195,11 +195,15 @@ files:
195
195
  - README.md
196
196
  - Rakefile.rb
197
197
  - lib/ur.rb
198
+ - lib/ur/content_type_attrs.rb
199
+ - lib/ur/faraday.rb
200
+ - lib/ur/faraday/yield_ur.rb
198
201
  - lib/ur/middleware.rb
199
202
  - lib/ur/processing.rb
200
203
  - lib/ur/request.rb
201
204
  - lib/ur/request_and_response.rb
202
205
  - lib/ur/response.rb
206
+ - lib/ur/sub_ur.rb
203
207
  - lib/ur/version.rb
204
208
  - test/test_helper.rb
205
209
  - test/ur_faraday_test.rb