diesel-api-dsl 0.0.1 → 0.1.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.
- checksums.yaml +5 -13
- data/Rakefile +5 -0
- data/diesel.gemspec +4 -0
- data/lib/diesel.rb +13 -5
- data/lib/diesel/api_base.rb +27 -0
- data/lib/diesel/api_builder.rb +98 -34
- data/lib/diesel/api_error.rb +3 -0
- data/lib/diesel/api_group.rb +27 -0
- data/lib/diesel/data_model.rb +24 -0
- data/lib/diesel/endpoint.rb +15 -33
- data/lib/diesel/middleware/auth/api_key.rb +27 -0
- data/lib/diesel/middleware/debug.rb +20 -0
- data/lib/diesel/middleware/set_body_parameter.rb +11 -0
- data/lib/diesel/middleware/set_header.rb +15 -0
- data/lib/diesel/middleware/set_parameter_base.rb +33 -0
- data/lib/diesel/middleware/set_path_parameter.rb +17 -0
- data/lib/diesel/middleware/set_query_parameter.rb +13 -0
- data/lib/diesel/middleware_builder.rb +15 -0
- data/lib/diesel/middleware_stack.rb +21 -0
- data/lib/diesel/request_context.rb +40 -15
- data/lib/diesel/swagger/data_type_field.rb +25 -0
- data/lib/diesel/swagger/definition.rb +12 -0
- data/lib/diesel/swagger/external_docs.rb +10 -0
- data/lib/diesel/swagger/info.rb +14 -0
- data/lib/diesel/swagger/node.rb +140 -0
- data/lib/diesel/swagger/operation.rb +22 -0
- data/lib/diesel/swagger/parameter.rb +32 -0
- data/lib/diesel/swagger/parser.rb +70 -0
- data/lib/diesel/swagger/path.rb +27 -0
- data/lib/diesel/swagger/property.rb +8 -0
- data/lib/diesel/swagger/security_definition.rb +15 -0
- data/lib/diesel/swagger/specification.rb +30 -0
- data/lib/diesel/utils/inflections.rb +46 -0
- data/lib/diesel/version.rb +1 -1
- data/spec/diesel/api_builder_spec.rb +14 -0
- data/spec/diesel/swagger/parser_spec.rb +80 -0
- data/spec/diesel_spec.rb +43 -0
- data/spec/files/honeybadger.json +80 -0
- data/spec/files/pivotal_tracker.json +94 -0
- data/spec/fixtures/vcr_cassettes/honeybadger.yml +98 -0
- data/spec/fixtures/vcr_cassettes/pivotal_tracker_create_story.yml +61 -0
- data/spec/spec_helper.rb +10 -0
- metadata +110 -25
- data/apis/pivotal_tracker.rb +0 -55
- data/examples/create_pivotal_task.rb +0 -13
- data/lib/diesel/action/http.rb +0 -92
- data/lib/diesel/api.rb +0 -33
- data/lib/diesel/auth/api_key.rb +0 -39
- data/lib/diesel/auth/base.rb +0 -8
- data/lib/diesel/auth/oauth2.rb +0 -13
- data/lib/diesel/authenticator.rb +0 -35
- data/lib/diesel/complex_type_builder.rb +0 -24
- data/lib/diesel/container_builder.rb +0 -6
- data/lib/diesel/dsl.rb +0 -239
- data/lib/diesel/model_builder.rb +0 -9
- data/lib/diesel/profile.rb +0 -112
@@ -0,0 +1,33 @@
|
|
1
|
+
module Diesel
|
2
|
+
module Middleware
|
3
|
+
class SetParameterBase
|
4
|
+
|
5
|
+
def initialize(app, options)
|
6
|
+
@app = app
|
7
|
+
@name = options[:name]
|
8
|
+
@schema = options[:schema]
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
value = find_parameter_value(env)
|
13
|
+
apply_parameter_value(env, value)
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def find_parameter_value(env)
|
20
|
+
if @schema
|
21
|
+
@schema.build(@name, env)
|
22
|
+
else
|
23
|
+
context = env[:context]
|
24
|
+
context.get_attribute(@name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def apply_parameter_value(env, value)
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'diesel/middleware/set_parameter_base'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
module Middleware
|
5
|
+
class SetPathParameter < SetParameterBase
|
6
|
+
|
7
|
+
def initialize(app, options)
|
8
|
+
super
|
9
|
+
@regex = Regexp.new(Regexp.quote("{#{@name}}"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def apply_parameter_value(env, value)
|
13
|
+
env[:url] = env[:url].gsub(@regex, value.to_s)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Diesel
|
2
|
+
class MiddlewareBuilder
|
3
|
+
def initialize(middlewares)
|
4
|
+
@middlewares = middlewares
|
5
|
+
end
|
6
|
+
|
7
|
+
def build(&block)
|
8
|
+
instance_eval(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def use(middleware_klass, options = {})
|
12
|
+
@middlewares << [middleware_klass, options]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Diesel
|
2
|
+
class MiddlewareStack
|
3
|
+
|
4
|
+
def initialize(middlewares)
|
5
|
+
cur = ->(env){}
|
6
|
+
middlewares.reverse.each do |(klass, options)|
|
7
|
+
cur = if klass.instance_method(:initialize).arity == 1
|
8
|
+
klass.new(cur)
|
9
|
+
else
|
10
|
+
klass.new(cur, options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
@first = cur
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@first.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -1,30 +1,55 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'diesel/utils/inflections'
|
3
|
+
|
1
4
|
module Diesel
|
2
5
|
class RequestContext
|
3
|
-
|
6
|
+
include Diesel::Utils::Inflections
|
7
|
+
|
8
|
+
attr_reader :options, :group, :endpoint, :attributes
|
4
9
|
|
5
|
-
def initialize(
|
6
|
-
@
|
10
|
+
def initialize(options, group, endpoint, attributes)
|
11
|
+
@options, @group, @endpoint, @attributes = options, group, endpoint, attributes
|
7
12
|
end
|
8
13
|
|
9
|
-
def
|
10
|
-
|
14
|
+
def perform
|
15
|
+
env = {
|
16
|
+
method: endpoint.request_method,
|
17
|
+
url: endpoint.url,
|
18
|
+
params: {},
|
19
|
+
request_headers: {},
|
20
|
+
logger: logger,
|
21
|
+
context: self
|
22
|
+
}
|
23
|
+
endpoint.middleware_stack.call(env)
|
24
|
+
perform_request(env)
|
11
25
|
end
|
12
26
|
|
13
|
-
def
|
14
|
-
|
15
|
-
attributes[name]
|
27
|
+
def authenticator
|
28
|
+
group.authenticator
|
16
29
|
end
|
17
30
|
|
18
31
|
def endpoint_url
|
19
|
-
url
|
20
|
-
url << "/" unless url =~ /\/$/
|
21
|
-
endpoint_path = endpoint.path
|
22
|
-
url << (endpoint_path =~ /^\// ? endpoint_path[1..-1] : endpoint_path)
|
23
|
-
url
|
32
|
+
endpoint.url
|
24
33
|
end
|
25
34
|
|
26
|
-
def
|
27
|
-
|
35
|
+
def logger
|
36
|
+
group.logger
|
28
37
|
end
|
38
|
+
|
39
|
+
def get_attribute(name)
|
40
|
+
name = name.to_sym
|
41
|
+
unless attributes.has_key?(name)
|
42
|
+
name = underscore(name).to_sym
|
43
|
+
end
|
44
|
+
attributes[name]
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
def perform_request(env)
|
49
|
+
HTTParty.send(env[:method], env[:url],
|
50
|
+
headers: env[:request_headers],
|
51
|
+
query: env[:params],
|
52
|
+
body: env[:body])
|
53
|
+
end
|
29
54
|
end
|
30
55
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'diesel/swagger/node'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
module Swagger
|
5
|
+
class DataTypeField < Node
|
6
|
+
attribute :type, symbolize: true
|
7
|
+
attribute :format
|
8
|
+
attribute :default_value
|
9
|
+
attribute :multiple_of
|
10
|
+
attribute :maximum
|
11
|
+
attribute :exclusive_maximum, type: :boolean
|
12
|
+
attribute :minimum
|
13
|
+
attribute :exclusive_minimum, type: :boolean
|
14
|
+
attribute :max_length
|
15
|
+
attribute :min_length
|
16
|
+
attribute :pattern
|
17
|
+
attribute :max_items
|
18
|
+
attribute :min_items
|
19
|
+
attribute :unique_items, type: :boolean
|
20
|
+
|
21
|
+
list :enum
|
22
|
+
list :items
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'diesel/utils/inflections'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
module Swagger
|
5
|
+
class Node
|
6
|
+
include Diesel::Utils::Inflections
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def inherited(base)
|
10
|
+
base.instance_variable_set(:@attribute_names, attribute_names.dup)
|
11
|
+
base.instance_variable_set(:@list_names, list_names.dup)
|
12
|
+
base.instance_variable_set(:@hash_names, hash_names.dup)
|
13
|
+
end
|
14
|
+
|
15
|
+
def attribute_names
|
16
|
+
@attribute_names || []
|
17
|
+
end
|
18
|
+
|
19
|
+
def list_names
|
20
|
+
@list_names || []
|
21
|
+
end
|
22
|
+
|
23
|
+
def hash_names
|
24
|
+
@hash_names || []
|
25
|
+
end
|
26
|
+
|
27
|
+
def attribute(name, options = {})
|
28
|
+
name = name.to_sym
|
29
|
+
(@attribute_names ||= []) << name
|
30
|
+
attr_accessor name
|
31
|
+
if options[:type] == :boolean
|
32
|
+
define_method("#{name}?".to_sym) do
|
33
|
+
!!send(name)
|
34
|
+
end
|
35
|
+
elsif options[:symbolize]
|
36
|
+
define_method("#{name}=".to_sym) do |value|
|
37
|
+
instance_variable_set("@#{name}".to_sym, value.nil? ? nil : value.to_sym)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
(@validates_children ||= []) << name if options[:validate]
|
41
|
+
end
|
42
|
+
|
43
|
+
def list(name, options = {})
|
44
|
+
attr_accessor name
|
45
|
+
(@list_names ||= []) << name
|
46
|
+
(@validates_children ||= []) << name if options[:validate]
|
47
|
+
end
|
48
|
+
|
49
|
+
def hash(name, options = {})
|
50
|
+
attr_accessor name
|
51
|
+
(@hash_names ||= []) << name
|
52
|
+
(@validates_children ||= []) << name if options[:validate]
|
53
|
+
end
|
54
|
+
|
55
|
+
def collect_errors(node, all_errors = [])
|
56
|
+
if @validates_children
|
57
|
+
@validates_children.each do |name|
|
58
|
+
if attr_val = node.send(name)
|
59
|
+
if @hash_names && @hash_names.include?(name)
|
60
|
+
attr_val.each_pair { |k,v| v.collect_errors(all_errors) }
|
61
|
+
|
62
|
+
elsif @list_names && @list_names.include?(name)
|
63
|
+
attr_val.each { |v| v.collect_errors(all_errors) }
|
64
|
+
|
65
|
+
else
|
66
|
+
unless attr_val.respond_to? :collect_errors
|
67
|
+
raise "Expecting #{name} to be a node"
|
68
|
+
end
|
69
|
+
attr_val.collect_errors(all_errors)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
all_errors
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :errors
|
79
|
+
|
80
|
+
def initialize
|
81
|
+
@errors = []
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate
|
85
|
+
end
|
86
|
+
|
87
|
+
def valid?
|
88
|
+
validate
|
89
|
+
@errors.any?
|
90
|
+
end
|
91
|
+
|
92
|
+
def collect_errors(all_errors = [])
|
93
|
+
validate; all_errors.concat(errors)
|
94
|
+
self.class.collect_errors(self, all_errors)
|
95
|
+
end
|
96
|
+
|
97
|
+
def serializable_hash
|
98
|
+
h = {}
|
99
|
+
|
100
|
+
if self.class.attribute_names
|
101
|
+
self.class.attribute_names.each do |nm|
|
102
|
+
if v = __send__(nm)
|
103
|
+
h[camelize(nm, false)] = value_or_serializable_hash(v)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
if self.class.list_names
|
109
|
+
self.class.list_names.each do |nm|
|
110
|
+
if arr = __send__(nm)
|
111
|
+
result = arr.map do |v|
|
112
|
+
value_or_serializable_hash(v)
|
113
|
+
end
|
114
|
+
h[camelize(nm, false)] = result if result.any?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
if self.class.hash_names
|
120
|
+
self.class.hash_names.each do |nm|
|
121
|
+
if value_hash = __send__(nm)
|
122
|
+
result = value_hash.reduce({}) do |m,(k,v)|
|
123
|
+
m[k] = value_or_serializable_hash(v); m
|
124
|
+
end
|
125
|
+
h[camelize(nm, false)] = result if result.any?
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
h
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def value_or_serializable_hash(v)
|
136
|
+
v.respond_to?(:serializable_hash) ? v.serializable_hash : v
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'diesel/swagger/node'
|
2
|
+
require 'diesel/swagger/parameter'
|
3
|
+
|
4
|
+
module Diesel
|
5
|
+
module Swagger
|
6
|
+
class Operation < Node
|
7
|
+
attribute :summary
|
8
|
+
attribute :description
|
9
|
+
attribute :external_docs, validate: true
|
10
|
+
attribute :operation_id
|
11
|
+
attribute :deprecated
|
12
|
+
|
13
|
+
list :tags
|
14
|
+
list :consumes
|
15
|
+
list :produces
|
16
|
+
list :parameters, validate: true
|
17
|
+
list :responses, validate: true
|
18
|
+
list :schemes
|
19
|
+
list :security, validate: true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'diesel/swagger/data_type_field'
|
2
|
+
|
3
|
+
module Diesel
|
4
|
+
module Swagger
|
5
|
+
class Parameter < DataTypeField
|
6
|
+
VALID_TYPES = %w(
|
7
|
+
string
|
8
|
+
number
|
9
|
+
integer
|
10
|
+
boolean
|
11
|
+
array
|
12
|
+
file
|
13
|
+
)
|
14
|
+
|
15
|
+
attribute :name
|
16
|
+
attribute :in, symbolize: true
|
17
|
+
attribute :description
|
18
|
+
attribute :required, type: :boolean
|
19
|
+
attribute :schema
|
20
|
+
|
21
|
+
def schema?
|
22
|
+
!!schema
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate
|
26
|
+
if type == :path && !required?
|
27
|
+
errors << "Path parameters must be defined as required"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|