ur 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08e517b90ad97d890764bc228d8836e7e48d7f8250ed7c3a4878368b77b2deb2'
4
- data.tar.gz: e87aedb3a622a5606bff0370cc1a06f43d98be53488389c1902e989226760cd1
3
+ metadata.gz: a39ab1a17905dc8a0fb40eb22896580951abec8cfe78a11c4a1fd558ca6c6917
4
+ data.tar.gz: 5915b4da516b30c6ee291eb7f5a5bb5a8f974d30da327d5660a9b1a0549068a8
5
5
  SHA512:
6
- metadata.gz: '069f50e6768b41beb13830308fd3a3d18845c32fc38f6e95755b8f929ba88e20efcfce8f84abf50ed393a93f9c2971bb7b280e5793d43098c06dc034f136487c'
7
- data.tar.gz: 42c005bf4853f4bb946a2bd143696c84fa84c6f933b71a6425505722aab150f290ab21265ac2b6e9fdaa313e0207becb46f5a14ff20a7cd2c18e4daa53d12084
6
+ metadata.gz: e59ca34e85e21e8c659a10e57cffad39d3fa718389bed6ccb6e4327cb33b237569517bb8d5c2eb93272a0c20634966697823a7142f1d861ba58c933dad5342c6
7
+ data.tar.gz: 3ab8ad92c6e70fc3dd87928a200a500e8bd5d27440fd9c2b3e35d46d3778aed80122cefda50875cb0bb6f84dcba75fbc24bdc194d88d4f345439b97f98f7b9b6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # v0.2.2
2
+
3
+ - Ur::Weblink
4
+ - JSI v0.7.0
5
+ - Ruby 3
6
+
7
+ # v0.2.1
8
+
9
+ - JSI v0.6.0
10
+
1
11
  # v0.2.0
2
12
 
3
13
  - Ur uses JSI schema modules instead of classes
data/README.md CHANGED
@@ -61,6 +61,6 @@ end
61
61
 
62
62
  ## License
63
63
 
64
- [<img align="right" src="https://github.com/notEthan/ur/raw/master/resources/icons/LGPL-3.0.png">](https://www.gnu.org/licenses/lgpl-3.0.html)
64
+ [<img align="right" src="https://www.gnu.org/graphics/lgplv3-147x51.png">](https://www.gnu.org/licenses/lgpl-3.0.html)
65
65
 
66
- Ur is Open Source Software licensed under the terms of the [GNU Lesser General Public License version 3](https://www.gnu.org/licenses/lgpl-3.0.html).
66
+ Ur is licensed under the terms of the [GNU Lesser General Public License version 3](https://www.gnu.org/licenses/lgpl-3.0.html).
@@ -21,12 +21,15 @@ module Ur
21
21
  # https://tools.ietf.org/html/rfc2045#section-5.1
22
22
  # - Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
23
23
  # https://tools.ietf.org/html/rfc2046
24
+ # - Additional Media Type Structured Syntax Suffixes
25
+ # https://tools.ietf.org/html/rfc6839
24
26
  class ContentType < String
25
27
  # the character ranges in this SHOULD be significantly more restrictive,
26
- # and the /<subtype> construct should not be optional. however, we'll aim
28
+ # and the `/<subtype>` construct should not be optional. however, we'll aim
27
29
  # to match whatever media type we are given.
28
30
  #
29
31
  # example:
32
+ #
30
33
  # MEDIA_TYPE_REGEXP.match('application/vnd.github+json').named_captures
31
34
  # =>
32
35
  # {
@@ -38,6 +41,7 @@ module Ur
38
41
  # }
39
42
  #
40
43
  # example of being more permissive than the spec allows:
44
+ #
41
45
  # MEDIA_TYPE_REGEXP.match('where the %$*! am I').named_captures
42
46
  # =>
43
47
  # {
@@ -116,46 +120,55 @@ module Ur
116
120
  freeze
117
121
  end
118
122
 
119
- # @return [String, nil] the media type of this content type.
120
- # e.g. "application/vnd.github+json" in content-type: application/vnd.github+json; charset="utf-8"
123
+ # the media type of this content type.
124
+ # e.g. `"application/vnd.github+json"` in `content-type: application/vnd.github+json; charset="utf-8"`
125
+ # @return [String, nil]
121
126
  attr_reader :media_type
122
127
 
123
- # @return [String, nil] the 'type' portion of our media type.
124
- # e.g. "application" in content-type: application/vnd.github+json; charset="utf-8"
128
+ # the 'type' portion of our media type.
129
+ # e.g. `"application"` in `content-type: application/vnd.github+json; charset="utf-8"`
130
+ # @return [String, nil]
125
131
  attr_reader :type
126
132
 
127
- # @return [String, nil] the 'subtype' portion of our media type.
128
- # e.g. "vnd.github+json" in content-type: application/vnd.github+json; charset="utf-8"
133
+ # the 'subtype' portion of our media type.
134
+ # e.g. `"vnd.github+json"` in `content-type: application/vnd.github+json; charset="utf-8"`
135
+ # @return [String, nil]
129
136
  attr_reader :subtype
130
137
 
131
- # @return [String, nil] the 'facet' portion of our media type.
132
- # e.g. "vnd" in content-type: application/vnd.github+json; charset="utf-8"
138
+ # the 'facet' portion of our media type.
139
+ # e.g. `"vnd"` in `content-type: application/vnd.github+json; charset="utf-8"`
140
+ # @return [String, nil]
133
141
  attr_reader :facet
134
142
 
135
- # @return [String, nil] the 'suffix' portion of our media type.
136
- # e.g. "json" in content-type: application/vnd.github+json; charset="utf-8"
143
+ # the 'suffix' portion of our media type.
144
+ # e.g. `"json"` in `content-type: application/vnd.github+json; charset="utf-8"`
145
+ # @return [String, nil]
137
146
  attr_reader :suffix
138
147
 
139
- # @return [Hash<String, String>] parameters of this content type.
140
- # e.g. {"charset" => "utf-8"} in content-type: application/vnd.github+json; charset="utf-8"
148
+ # parameters of this content type.
149
+ # e.g. `{"charset" => "utf-8"}` in `content-type: application/vnd.github+json; charset="utf-8"`
150
+ # @return [Hash<String, String>]
141
151
  attr_reader :parameters
142
152
 
153
+ # is the 'type' portion of our media type equal (case-insensitive) to the given other_type
143
154
  # @param other_type
144
- # @return [Boolean] is the 'type' portion of our media type equal (case-insensitive) to the given other_type
155
+ # @return [Boolean]
145
156
  def type?(other_type)
146
- type && type.casecmp?(other_type)
157
+ type ? type.casecmp?(other_type) : false
147
158
  end
148
159
 
160
+ # is the 'subtype' portion of our media type equal (case-insensitive) to the given other_subtype
149
161
  # @param other_subtype
150
- # @return [Boolean] is the 'subtype' portion of our media type equal (case-insensitive) to the given other_subtype
162
+ # @return [Boolean]
151
163
  def subtype?(other_subtype)
152
- subtype && subtype.casecmp?(other_subtype)
164
+ subtype ? subtype.casecmp?(other_subtype) : false
153
165
  end
154
166
 
167
+ # is the 'suffix' portion of our media type equal (case-insensitive) to the given other_suffix
155
168
  # @param other_suffix
156
- # @return [Boolean] is the 'suffix' portion of our media type equal (case-insensitive) to the given other_suffix
169
+ # @return [Boolean]
157
170
  def suffix?(other_suffix)
158
- suffix && suffix.casecmp?(other_suffix)
171
+ suffix ? suffix.casecmp?(other_suffix) : false
159
172
  end
160
173
 
161
174
  SOME_TEXT_SUBTYPES = %w(
@@ -173,11 +186,12 @@ module Ur
173
186
  ecmascript
174
187
  ).map(&:freeze).freeze
175
188
 
189
+ # does this content type appear to be binary?
190
+ # this library makes its best guess based on a very incomplete knowledge
191
+ # of which media types indicate binary or text.
176
192
  # @param unknown [Boolean] return this value when we have no idea whether
177
193
  # our media type is binary or text.
178
- # @return [Boolean] does this content type appear to be binary?
179
- # this library makes its best guess based on a very incomplete knowledge
180
- # of which media types indicate binary or text.
194
+ # @return [Boolean]
181
195
  def binary?(unknown: true)
182
196
  return false if type_text?
183
197
 
@@ -192,54 +206,64 @@ module Ur
192
206
  return unknown
193
207
  end
194
208
 
195
- # @return [Boolean] is this a JSON content type?
209
+ # is this a JSON content type?
210
+ # @return [Boolean]
196
211
  def json?
197
212
  suffix ? suffix.casecmp?('json') : subtype ? subtype.casecmp?('json') : false
198
213
  end
199
214
 
200
- # @return [Boolean] is this an XML content type?
215
+ # is this an XML content type?
216
+ # @return [Boolean]
201
217
  def xml?
202
- suffix ? suffix.casecmp?('xml'): subtype ? subtype.casecmp?('xml') : false
218
+ suffix ? suffix.casecmp?('xml') : subtype ? subtype.casecmp?('xml') : false
203
219
  end
204
220
 
205
- # @return [Boolean] is this a x-www-form-urlencoded content type?
221
+ # is this a `x-www-form-urlencoded` content type?
222
+ # @return [Boolean]
206
223
  def form_urlencoded?
207
- suffix ? suffix.casecmp?('x-www-form-urlencoded'): subtype ? subtype.casecmp?('x-www-form-urlencoded') : false
224
+ suffix ? suffix.casecmp?('x-www-form-urlencoded') : subtype ? subtype.casecmp?('x-www-form-urlencoded') : false
208
225
  end
209
226
 
210
- # @return [Boolean] is the 'type' portion of our media type 'text'
227
+ # is the 'type' portion of our media type 'text'
228
+ # @return [Boolean]
211
229
  def type_text?
212
- type && type.casecmp?('text')
230
+ type ? type.casecmp?('text') : false
213
231
  end
214
232
 
215
- # @return [Boolean] is the 'type' portion of our media type 'image'
233
+ # is the 'type' portion of our media type 'image'
234
+ # @return [Boolean]
216
235
  def type_image?
217
- type && type.casecmp?('image')
236
+ type ? type.casecmp?('image') : false
218
237
  end
219
238
 
220
- # @return [Boolean] is the 'type' portion of our media type 'audio'
239
+ # is the 'type' portion of our media type 'audio'
240
+ # @return [Boolean]
221
241
  def type_audio?
222
- type && type.casecmp?('audio')
242
+ type ? type.casecmp?('audio') : false
223
243
  end
224
244
 
225
- # @return [Boolean] is the 'type' portion of our media type 'video'
245
+ # is the 'type' portion of our media type 'video'
246
+ # @return [Boolean]
226
247
  def type_video?
227
- type && type.casecmp?('video')
248
+ type ? type.casecmp?('video') : false
228
249
  end
229
250
 
230
- # @return [Boolean] is the 'type' portion of our media type 'application'
251
+ # is the 'type' portion of our media type 'application'
252
+ # @return [Boolean]
231
253
  def type_application?
232
- type && type.casecmp?('application')
254
+ type ? type.casecmp?('application') : false
233
255
  end
234
256
 
235
- # @return [Boolean] is the 'type' portion of our media type 'message'
257
+ # is the 'type' portion of our media type 'message'
258
+ # @return [Boolean]
236
259
  def type_message?
237
- type && type.casecmp?('message')
260
+ type ? type.casecmp?('message') : false
238
261
  end
239
262
 
240
- # @return [Boolean] is the 'type' portion of our media type 'multipart'
263
+ # is the 'type' portion of our media type 'multipart'
264
+ # @return [Boolean]
241
265
  def type_multipart?
242
- type && type.casecmp?('multipart')
266
+ type ? type.casecmp?('multipart') : false
243
267
  end
244
268
  end
245
269
  end
data/lib/ur/middleware.rb CHANGED
@@ -30,7 +30,7 @@ module Ur
30
30
  class FaradayMiddleware < ::Faraday::Middleware
31
31
  include Ur::Middleware
32
32
  def call(request_env)
33
- ur = Ur.from_faraday_request(request_env, @options.select { |k, _| [:schemas].include?(k) })
33
+ ur = Ur.from_faraday_request(request_env, **@options.select { |k, _| [:schemas].include?(k) })
34
34
  invoke_callback(:before_request, ur)
35
35
  begin_request(ur)
36
36
  ur.faraday_on_complete(@app, request_env) do |response_env|
@@ -43,7 +43,7 @@ module Ur
43
43
  class RackMiddleware
44
44
  include Ur::Middleware
45
45
  def call(env)
46
- ur = Ur.from_rack_request(env, @options.select { |k, _| [:schemas].include?(k) })
46
+ ur = Ur.from_rack_request(env, **@options.select { |k, _| [:schemas].include?(k) })
47
47
  invoke_callback(:before_request, ur)
48
48
  begin_request(ur)
49
49
  ur.with_rack_response(@app, env) do
@@ -25,9 +25,10 @@ module Ur
25
25
  end
26
26
  include FaradayEntity
27
27
 
28
- # @return [Ur::ContentType] the string value of the content type header. returns an
28
+ # the string value of the content type header. returns an
29
29
  # {Ur::ContentType}, a subclass of String which additionally parses the Content-Type
30
30
  # according to relevant RFCs.
31
+ # @return [Ur::ContentType]
31
32
  def content_type
32
33
  headers.each do |k, v|
33
34
  return ContentType.new(v) if k =~ /\Acontent[-_]type\z/i
@@ -40,17 +41,20 @@ module Ur
40
41
  content_type ? content_type.media_type : nil
41
42
  end
42
43
 
43
- # @return [Boolean] is our content type JSON?
44
+ # is our content type JSON?
45
+ # @return [Boolean]
44
46
  def json?
45
47
  content_type && content_type.json?
46
48
  end
47
49
 
48
- # @return [Boolean] is our content type XML?
50
+ # is our content type XML?
51
+ # @return [Boolean]
49
52
  def xml?
50
53
  content_type && content_type.xml?
51
54
  end
52
55
 
53
- # @return [Boolean] is our content type x-www-form-urlencoded?
56
+ # is our content type `x-www-form-urlencoded`?
57
+ # @return [Boolean]
54
58
  def form_urlencoded?
55
59
  content_type && content_type.form_urlencoded?
56
60
  end
data/lib/ur/sub_ur.rb CHANGED
@@ -5,7 +5,7 @@ require 'ur' unless Object.const_defined?(:Ur)
5
5
  module Ur
6
6
  module SubUr
7
7
  def ur
8
- parent_jsis.detect { |p| p.is_a?(::Ur) }
8
+ jsi_parent_nodes.detect { |p| p.is_a?(::Ur) }
9
9
  end
10
10
  end
11
11
  end
data/lib/ur/version.rb CHANGED
@@ -1 +1 @@
1
- UR_VERSION = "0.2.0".freeze
1
+ UR_VERSION = "0.2.2".freeze
data/lib/ur/weblink.rb ADDED
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ur' unless Object.const_defined?(:Ur)
4
+
5
+ module Ur
6
+ # a RFC5988 Web Link
7
+ #
8
+ # https://tools.ietf.org/html/rfc5988
9
+ class Weblink
10
+ # Weblink::Error, base class for all errors of the Weblink class
11
+ class Error < StandardError
12
+ end
13
+
14
+ # error parsing a Weblink
15
+ class ParseError < Error
16
+ end
17
+
18
+ # error when attempting an operation that requires a context URI which was not provided
19
+ class NoContextError < Error
20
+ end
21
+
22
+ # parses an array of Web Links from the value an HTTP Link header, as described in
23
+ # https://tools.ietf.org/html/rfc5988#section-5
24
+ #
25
+ # returns an Array of Weblink objects
26
+ def self.parse_link_value(link_value, context_uri=nil)
27
+ links = []
28
+
29
+ return links unless link_value
30
+
31
+ attr_char = /[a-zA-Z0-9!#\$&+\-.^_`|~]/ # defined in https://tools.ietf.org/html/rfc5987#section-3.2.1
32
+ ptoken = %r([a-zA-Z0-9!#\$%&'()*+\-./:<=>?@\[\]^_`{|}~])
33
+ quoted_string = /"([^"]*)"/
34
+
35
+ require 'strscan'
36
+ ss = StringScanner.new(link_value)
37
+ parse_fail = proc do
38
+ raise ParseError, "Unable to parse link value: #{link_value} " +
39
+ "around character #{ss.pos}: #{ss.peek(link_value.length - ss.pos)}"
40
+ end
41
+
42
+ while !ss.eos?
43
+ # get the target_uri, within some angle brackets
44
+ ss.scan(/\s*<([^>]+)>/) || parse_fail.call
45
+ target_uri = ss[1]
46
+ attributes = {}
47
+ # get the attributes: semicolon, some attr_chars, an optional asterisk, equals, and a quoted
48
+ # string or series of unquoted ptokens
49
+ while ss.scan(/\s*;\s*(#{attr_char.source}+\*?)\s*=\s*(?:#{quoted_string.source}|(#{ptoken.source}+))\s*/)
50
+ attributes[ss[1]] = ss[2] || ss[3]
51
+ end
52
+ links << new(target_uri, attributes, context_uri)
53
+ unless ss.eos?
54
+ # either the string ends or has a comma followed by another link
55
+ ss.scan(/\s*,\s*/) || parse_fail.call
56
+ end
57
+ end
58
+ links
59
+ end
60
+
61
+ def initialize(target_uri, attributes, context_uri=nil)
62
+ @target_uri = to_addressable_uri(target_uri)
63
+ @attributes = attributes
64
+ @context_uri = to_addressable_uri(context_uri)
65
+ end
66
+
67
+ # the context uri of the link, as an Addressable URI. this URI must be absolute, and the target_uri
68
+ # may be resolved against it. this is most typically the request URI of a request to a service
69
+ attr_reader :context_uri
70
+
71
+ # RFC 5988 calls it IRI, but nobody else does. we'll throw in an alias.
72
+ alias_method :context_iri, :context_uri
73
+
74
+ # returns the target URI as an Addressable::URI
75
+ attr_reader :target_uri
76
+
77
+ # RFC 5988 calls it IRI, but nobody else does. we'll throw in an alias.
78
+ alias_method :target_iri, :target_uri
79
+
80
+ # attempts to make target_uri absolute, using context_uri if available. raises if
81
+ # there is not information available to make an absolute target URI
82
+ def absolute_target_uri
83
+ if target_uri.absolute?
84
+ target_uri
85
+ elsif context_uri
86
+ context_uri + target_uri
87
+ else
88
+ raise NoContextError, "Target URI is relative but no Context URI given - cannot determine absolute target URI"
89
+ end
90
+ end
91
+
92
+ # link attributes
93
+ attr_reader :attributes
94
+
95
+ # subscript returns an attribute of this Link, if defined, otherwise nil
96
+ def [](attribute_key)
97
+ @attributes[attribute_key]
98
+ end
99
+
100
+ # link rel attribute
101
+ def rel
102
+ self['rel']
103
+ end
104
+
105
+ alias_method :relation_type, :rel
106
+
107
+ # compares relation types in a case-insensitive manner as mandated in
108
+ # https://tools.ietf.org/html/rfc5988#section-4.1
109
+ def rel?(other_rel)
110
+ rel && other_rel && rel.downcase == other_rel.downcase
111
+ end
112
+
113
+ # a string of this weblink, appropriate for adding to a Link header
114
+ def to_s
115
+ "<#{target_uri}>" + attributes.map { |k,v| %Q(; #{k}="#{v}") }.join('')
116
+ end
117
+
118
+ private
119
+
120
+ # if uri is nil, returns nil; otherwise, tries to return a Addressable::URI
121
+ def to_addressable_uri(uri)
122
+ uri.nil? || uri.is_a?(Addressable::URI) ? uri : Addressable::URI.parse(uri)
123
+ end
124
+ end
125
+ end
data/lib/ur.rb CHANGED
@@ -6,9 +6,10 @@ require 'jsi'
6
6
  require 'time'
7
7
  require 'addressable/uri'
8
8
  require 'pathname'
9
+ require 'yaml'
9
10
 
10
11
  UR_ROOT = Pathname.new(__FILE__).dirname.parent.expand_path
11
- Ur = JSI::Schema.new(YAML.load_file(UR_ROOT.join('resources/ur.schema.yml'))).jsi_schema_module
12
+ Ur = JSI.new_schema_module(YAML.load_file(UR_ROOT.join('resources/ur.schema.yml')))
12
13
  module Ur
13
14
  VERSION = UR_VERSION
14
15
 
@@ -18,10 +19,11 @@ module Ur
18
19
  autoload :FaradayMiddleware, 'ur/middleware'
19
20
  autoload :RackMiddleware, 'ur/middleware'
20
21
  autoload :Faraday, 'ur/faraday'
22
+ autoload :Weblink, 'ur/weblink'
21
23
 
22
- Request = self.schema.properties['request'].jsi_schema_module
23
- Response = self.schema.properties['response'].jsi_schema_module
24
- Metadata = self.schema.properties['metadata'].jsi_schema_module
24
+ Request = self.properties['request']
25
+ Response = self.properties['response']
26
+ Metadata = self.properties['metadata']
25
27
  require 'ur/request'
26
28
  require 'ur/response'
27
29
  require 'ur/metadata'
@@ -34,8 +36,7 @@ module Ur
34
36
  raise(TypeError, "expected hash for ur instance. got: #{instance.pretty_inspect.chomp}")
35
37
  end
36
38
 
37
- ur_class = JSI.class_for_schemas(Set[schema] + schemas)
38
- ur_class.new(instance, options).tap do |ur|
39
+ JSI::SchemaSet[schema, *schemas].new_jsi(instance, **options).tap do |ur|
39
40
  ur.request = {} if ur.request.nil?
40
41
  ur.response = {} if ur.response.nil?
41
42
  ur.metadata = {} if ur.metadata.nil?
@@ -51,7 +52,7 @@ module Ur
51
52
  env = request_env
52
53
  end
53
54
 
54
- new({'bound' => 'inbound'}, options).tap do |ur|
55
+ new({'bound' => 'inbound'}, **options).tap do |ur|
55
56
  ur.request['method'] = rack_request.request_method
56
57
 
57
58
  ur.request.addressable_uri = Addressable::URI.new(
@@ -82,7 +83,7 @@ module Ur
82
83
  end
83
84
 
84
85
  def from_faraday_request(request_env, **options)
85
- new({'bound' => 'outbound'}, options).tap do |ur|
86
+ new({'bound' => 'outbound'}, **options).tap do |ur|
86
87
  ur.request['method'] = request_env[:method].to_s
87
88
  ur.request.uri = request_env[:url].normalize.to_s
88
89
  ur.request.headers = request_env[:request_headers]
@@ -114,7 +115,7 @@ module Ur
114
115
  [status, response_headers, response_body_proxy]
115
116
  end
116
117
 
117
- def faraday_on_complete(app, request_env, &block)
118
+ def faraday_on_complete(app, request_env)
118
119
  app.call(request_env).on_complete do |response_env|
119
120
  response.status = response_env[:status]
120
121
  response.headers = response_env[:response_headers]
@@ -1,3 +1,4 @@
1
+ $schema: http://json-schema.org/draft-07/schema
1
2
  $id: https://schemas.ur.unth.net/ur
2
3
  type: object
3
4
  properties:
data/ur.gemspec CHANGED
@@ -6,28 +6,25 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "ur"
7
7
  spec.version = UR_VERSION
8
8
  spec.authors = ["Ethan"]
9
- spec.email = ["ethan@unth"]
9
+ spec.email = ["ethan.ur@unth.net"]
10
10
 
11
11
  spec.summary = 'ur: unified request representation'
12
12
  spec.description = 'ur provides a unified representation of a request and response. it can be interpreted from rack, faraday, or potentially other sources, and provides a consistent interface to access the attributes inherent to the request and additional useful parsers and computation from the request.'
13
13
  spec.homepage = "https://github.com/notEthan/ur"
14
14
  spec.license = "LGPL-3.0"
15
15
 
16
- ignore_files = %w(.gitignore .travis.yml Gemfile test)
17
- ignore_files_re = %r{\A(#{ignore_files.map { |f| Regexp.escape(f) }.join('|')})(/|\z)}
18
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(ignore_files_re) }
19
- spec.test_files = `git ls-files -z test`.split("\x0") + ['.simplecov']
16
+ spec.files = [
17
+ 'LICENSE.md',
18
+ 'CHANGELOG.md',
19
+ 'README.md',
20
+ '.yardopts',
21
+ 'resources/ur.schema.yml',
22
+ 'ur.gemspec',
23
+ *Dir['lib/**/*'],
24
+ ].reject { |f| File.lstat(f).ftype == 'directory' }
25
+
20
26
  spec.require_paths = ["lib"]
21
27
 
22
- spec.add_dependency "jsi", "~> 0.4"
28
+ spec.add_dependency "jsi", "~> 0.6"
23
29
  spec.add_dependency "addressable", "~> 2.0"
24
- spec.add_development_dependency "rack"
25
- spec.add_development_dependency "rack-test"
26
- spec.add_development_dependency "faraday"
27
- spec.add_development_dependency "faraday_middleware"
28
- spec.add_development_dependency "activesupport"
29
- spec.add_development_dependency "rake"
30
- spec.add_development_dependency "minitest"
31
- spec.add_development_dependency "minitest-reporters"
32
- spec.add_development_dependency "simplecov"
33
30
  end