interpol 0.9.0 → 0.10.0
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.
- data/Gemfile +0 -2
- data/lib/interpol/configuration.rb +28 -24
- data/lib/interpol/endpoint.rb +35 -7
- data/lib/interpol/version.rb +1 -1
- metadata +20 -5
- data/lib/interpol/configuration_ruby_18_extensions.rb +0 -27
data/Gemfile
CHANGED
@@ -13,8 +13,6 @@ gem 'compass_twitter_bootstrap', :git => 'git://github.com/vwall/compass-twitter
|
|
13
13
|
|
14
14
|
gem 'json', :platform => 'ruby_18'
|
15
15
|
|
16
|
-
gem 'sinatra', '>= 1.3.2', '< 2.0.0'
|
17
|
-
|
18
16
|
gem 'cane', '~> 2.0', :platform => 'ruby_19'
|
19
17
|
|
20
18
|
gem 'rspec-fire', :git => 'git://github.com/xaviershay/rspec-fire.git'
|
@@ -1,7 +1,7 @@
|
|
1
|
+
require 'interpol'
|
1
2
|
require 'interpol/endpoint'
|
2
3
|
require 'interpol/errors'
|
3
4
|
require 'yaml'
|
4
|
-
require 'interpol/configuration_ruby_18_extensions' if RUBY_VERSION.to_f < 1.9
|
5
5
|
require 'uri'
|
6
6
|
|
7
7
|
module Interpol
|
@@ -33,8 +33,9 @@ module Interpol
|
|
33
33
|
|
34
34
|
# Public: Defines interpol configuration.
|
35
35
|
class Configuration
|
36
|
-
attr_reader :endpoint_definition_files, :endpoints, :filter_example_data_blocks
|
37
|
-
|
36
|
+
attr_reader :endpoint_definition_files, :endpoints, :filter_example_data_blocks,
|
37
|
+
:endpoint_definition_merge_key_files
|
38
|
+
attr_accessor :validation_mode, :documentation_title
|
38
39
|
|
39
40
|
def initialize
|
40
41
|
self.endpoint_definition_files = []
|
@@ -48,16 +49,25 @@ module Interpol
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def endpoint_definition_files=(files)
|
51
|
-
|
52
|
-
Endpoint.new(deserialized_hash_from file)
|
53
|
-
end
|
52
|
+
@endpoints = nil
|
54
53
|
@endpoint_definition_files = files
|
55
54
|
end
|
56
55
|
|
56
|
+
def endpoint_definition_merge_key_files=(files)
|
57
|
+
@endpoints = nil
|
58
|
+
@endpoint_definition_merge_key_files = files
|
59
|
+
end
|
60
|
+
|
57
61
|
def endpoints=(endpoints)
|
58
62
|
@endpoints = endpoints.extend(DefinitionFinder)
|
59
63
|
end
|
60
64
|
|
65
|
+
def endpoints
|
66
|
+
@endpoints ||= @endpoint_definition_files.map do |file|
|
67
|
+
Endpoint.new(deserialized_hash_from(file), self)
|
68
|
+
end.extend(DefinitionFinder)
|
69
|
+
end
|
70
|
+
|
61
71
|
[:request, :response].each do |type|
|
62
72
|
class_eval <<-EOEVAL, __FILE__, __LINE__ + 1
|
63
73
|
def #{type}_version(version = nil, &block)
|
@@ -156,6 +166,15 @@ module Interpol
|
|
156
166
|
selector.call(endpoint_def, env)
|
157
167
|
end
|
158
168
|
|
169
|
+
def scalars_nullable_by_default=(value)
|
170
|
+
@endpoints = nil
|
171
|
+
@scalars_nullable_by_default = value
|
172
|
+
end
|
173
|
+
|
174
|
+
def scalars_nullable_by_default?
|
175
|
+
@scalars_nullable_by_default
|
176
|
+
end
|
177
|
+
|
159
178
|
def self.default
|
160
179
|
@default ||= Configuration.new
|
161
180
|
end
|
@@ -183,24 +202,9 @@ module Interpol
|
|
183
202
|
end
|
184
203
|
|
185
204
|
private
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
BAD_ALIAS_ERROR = defined?(::Psych::BadAlias) ?
|
190
|
-
::Psych::BadAlias : TypeError
|
191
|
-
def deserialized_hash_from(file)
|
192
|
-
YAML.load(yaml_content_for file)
|
193
|
-
rescue BAD_ALIAS_ERROR => e
|
194
|
-
raise ConfigurationError.new \
|
195
|
-
"Received an error while loading YAML from #{file}: \"" +
|
196
|
-
"#{e.class}: #{e.message}\" If you are using YAML merge keys " +
|
197
|
-
"to declare shared types, you must configure endpoint_definition_merge_key_files " +
|
198
|
-
"before endpoint_definition_files.", e
|
199
|
-
end
|
200
|
-
}
|
201
|
-
|
202
|
-
# Needed to override deserialized_hash_from for Ruby 1.8
|
203
|
-
include Interpol::ConfigurationRuby18Extensions if RUBY_VERSION.to_f < 1.9
|
205
|
+
def deserialized_hash_from(file)
|
206
|
+
YAML.load(yaml_content_for file)
|
207
|
+
end
|
204
208
|
|
205
209
|
def yaml_content_for(file)
|
206
210
|
File.read(file).gsub(/\A---\n/, "---\n" + endpoint_merge_keys + "\n\n")
|
data/lib/interpol/endpoint.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'json-schema'
|
2
2
|
require 'interpol/errors'
|
3
3
|
require 'forwardable'
|
4
|
+
require 'set'
|
4
5
|
|
5
6
|
module JSON
|
6
7
|
# The JSON-schema namespace
|
@@ -65,13 +66,14 @@ module Interpol
|
|
65
66
|
# based on the endpoint definitions in the YAML files.
|
66
67
|
class Endpoint
|
67
68
|
include HashFetcher
|
68
|
-
attr_reader :name, :route, :method, :custom_metadata
|
69
|
+
attr_reader :name, :route, :method, :custom_metadata, :configuration
|
69
70
|
|
70
|
-
def initialize(endpoint_hash)
|
71
|
+
def initialize(endpoint_hash, configuration = Interpol.default_configuration)
|
71
72
|
@name = fetch_from(endpoint_hash, 'name')
|
72
73
|
@route = fetch_from(endpoint_hash, 'route')
|
73
74
|
@method = fetch_from(endpoint_hash, 'method').downcase.to_sym
|
74
75
|
|
76
|
+
@configuration = configuration
|
75
77
|
@custom_metadata = endpoint_hash.fetch('meta') { {} }
|
76
78
|
|
77
79
|
@definitions_hash, @all_definitions = extract_definitions_from(endpoint_hash)
|
@@ -181,7 +183,7 @@ module Interpol
|
|
181
183
|
attr_reader :endpoint, :message_type, :version, :schema,
|
182
184
|
:path_params, :query_params, :examples, :custom_metadata
|
183
185
|
extend Forwardable
|
184
|
-
def_delegators :endpoint, :route
|
186
|
+
def_delegators :endpoint, :route, :configuration
|
185
187
|
|
186
188
|
DEFAULT_PARAM_HASH = { 'type' => 'object', 'properties' => {} }
|
187
189
|
|
@@ -244,12 +246,14 @@ module Interpol
|
|
244
246
|
end
|
245
247
|
end
|
246
248
|
|
247
|
-
def make_schema_hash_strict!(raw_schema,
|
249
|
+
def make_schema_hash_strict!(raw_schema, make_this_schema_strict=true)
|
250
|
+
conditionally_make_nullable(raw_schema) if make_this_schema_strict
|
251
|
+
|
248
252
|
raw_schema.each do |key, value|
|
249
253
|
make_schema_strict!(value, key != 'properties')
|
250
254
|
end
|
251
255
|
|
252
|
-
return unless
|
256
|
+
return unless make_this_schema_strict
|
253
257
|
|
254
258
|
if raw_schema.has_key?('properties')
|
255
259
|
raw_schema['additionalProperties'] ||= false
|
@@ -258,9 +262,33 @@ module Interpol
|
|
258
262
|
raw_schema['required'] = !raw_schema.delete('optional')
|
259
263
|
end
|
260
264
|
|
261
|
-
def make_schema_array_strict!(raw_schema,
|
265
|
+
def make_schema_array_strict!(raw_schema, make_nested_schemas_strict=true)
|
262
266
|
raw_schema.each do |entry|
|
263
|
-
make_schema_strict!(entry,
|
267
|
+
make_schema_strict!(entry, make_nested_schemas_strict)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def conditionally_make_nullable(raw_schema)
|
272
|
+
return unless should_be_nullable?(raw_schema)
|
273
|
+
|
274
|
+
types = Array(raw_schema['type'])
|
275
|
+
return if types.none? || types.include?('null')
|
276
|
+
|
277
|
+
raw_schema['type'] = (types << "null")
|
278
|
+
end
|
279
|
+
|
280
|
+
def should_be_nullable?(raw_schema)
|
281
|
+
raw_schema.fetch('nullable') do
|
282
|
+
configuration.scalars_nullable_by_default? && scalar?(raw_schema)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
NON_SCALAR_TYPES = %w[ object array ]
|
287
|
+
def scalar?(raw_schema)
|
288
|
+
types = Array(raw_schema['type']).to_set
|
289
|
+
|
290
|
+
NON_SCALAR_TYPES.none? do |non_scalar|
|
291
|
+
types.include?(non_scalar)
|
264
292
|
end
|
265
293
|
end
|
266
294
|
|
data/lib/interpol/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interpol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -66,14 +66,14 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: '2.
|
69
|
+
version: '2.13'
|
70
70
|
none: false
|
71
71
|
type: :development
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '2.
|
76
|
+
version: '2.13'
|
77
77
|
none: false
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: rspec-fire
|
@@ -171,6 +171,22 @@ dependencies:
|
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '1.2'
|
173
173
|
none: false
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: sinatra
|
176
|
+
prerelease: false
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ~>
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '1.4'
|
182
|
+
none: false
|
183
|
+
type: :development
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ~>
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '1.4'
|
189
|
+
none: false
|
174
190
|
description: Interpol is a toolkit for working with API endpoint definition files,
|
175
191
|
giving you a stub app, a schema validation middleware, and browsable documentation.
|
176
192
|
email:
|
@@ -186,7 +202,6 @@ files:
|
|
186
202
|
- lib/interpol/configuration/built_in_param_parsers.rb
|
187
203
|
- lib/interpol/configuration/default_callbacks.rb
|
188
204
|
- lib/interpol/configuration.rb
|
189
|
-
- lib/interpol/configuration_ruby_18_extensions.rb
|
190
205
|
- lib/interpol/documentation.rb
|
191
206
|
- lib/interpol/documentation_app/config.rb
|
192
207
|
- lib/interpol/documentation_app.rb
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Interpol
|
2
|
-
module ConfigurationRuby18Extensions
|
3
|
-
def deserialized_hash_from(file)
|
4
|
-
YAML.load(yaml_content_for file).tap do |yaml|
|
5
|
-
if bad_class = bad_deserialized_yaml(yaml)
|
6
|
-
raise ConfigurationError.new \
|
7
|
-
"Received an error while loading YAML from #{file}: \"" +
|
8
|
-
"Got object of type: #{bad_class}\"\n If you are using YAML merge keys " +
|
9
|
-
"to declare shared types, you must configure endpoint_definition_merge_key_files " +
|
10
|
-
"before endpoint_definition_files."
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# returns nil if the YAML has been only partially deserialized by Syck
|
16
|
-
# and there are YAML::Syck objects.
|
17
|
-
def bad_deserialized_yaml(yaml)
|
18
|
-
if [Hash, Array].include? yaml.class
|
19
|
-
yaml.map { |elem| bad_deserialized_yaml(elem) }.compact.first
|
20
|
-
elsif yaml.class.name =~ /YAML::Syck::/
|
21
|
-
yaml.class.name # Bad!
|
22
|
-
else
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|