lurker 0.6.8 → 1.0.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 -5
- data/.hound.yml +4 -78
- data/.jshintrc +33 -0
- data/.rspec +1 -2
- data/.rubocop.yml +0 -1
- data/.travis.yml +30 -19
- data/Gemfile +0 -33
- data/README.md +32 -53
- data/Rakefile +3 -3
- data/cucumber.yml +1 -2
- data/features/atom_persistent_within_the_same_type.feature +4 -4
- data/features/controller_nested_schema_scaffolding.feature +7 -10
- data/features/controller_schema_scaffolding.feature +1 -3
- data/features/dereferencing_through_inlining.feature +1 -3
- data/features/html_generation.feature +26 -4
- data/features/minitest.feature +3 -8
- data/features/multidomain_support.feature +6 -10
- data/features/multitype_request_support.feature +1 -3
- data/features/partials.feature +3 -8
- data/features/request_nested_schema_scaffolding.feature +0 -2
- data/features/request_schema_scaffolding.feature +0 -2
- data/features/schema_suffixes.feature +2 -18
- data/features/schema_updating_within_test_suite.feature +2 -6
- data/features/step_definitions/additional_cli_steps.rb +16 -12
- data/features/support/env.rb +50 -10
- data/features/test_endpoint.feature +2 -9
- data/gemfiles/rails_4.gemfile +14 -0
- data/gemfiles/rails_5.gemfile +10 -0
- data/gemfiles/rails_6.gemfile +10 -0
- data/lib/lurker.rb +9 -2
- data/lib/lurker/cli.rb +148 -128
- data/lib/lurker/endpoint.rb +11 -7
- data/lib/lurker/form_builder.rb +22 -31
- data/lib/lurker/json/concerns/validatable.rb +5 -1
- data/lib/lurker/json/parser.rb +1 -1
- data/lib/lurker/json/schema.rb +19 -6
- data/lib/lurker/json/{writter.rb → writer.rb} +2 -2
- data/lib/lurker/presenters/base_presenter.rb +10 -34
- data/lib/lurker/presenters/endpoint_presenter.rb +19 -8
- data/lib/lurker/presenters/schema_presenter.rb +6 -5
- data/lib/lurker/presenters/service_presenter.rb +41 -7
- data/lib/lurker/rendering_controller.rb +14 -7
- data/lib/lurker/service.rb +27 -11
- data/lib/lurker/spec_helper/rspec.rb +0 -4
- data/lib/lurker/spy.rb +3 -1
- data/lib/lurker/templates/documentation.md.tt +1 -0
- data/lib/lurker/templates/javascripts/lurker.js +133 -91
- data/lib/lurker/templates/layouts/_sidemenu.html.erb +2 -2
- data/lib/lurker/templates/layouts/application.html.erb +54 -57
- data/lib/lurker/templates/layouts/print.html.erb +31 -0
- data/lib/lurker/templates/lurker/rendering/_endpoint.html.erb +37 -0
- data/lib/lurker/templates/lurker/rendering/_param_form_element.html.erb +1 -1
- data/lib/lurker/templates/lurker/rendering/_service.html.erb +7 -0
- data/lib/lurker/templates/lurker/rendering/_submit_form.html.erb +77 -73
- data/lib/lurker/templates/lurker/rendering/all.html.erb +5 -0
- data/lib/lurker/templates/lurker/rendering/index.html.erb +1 -10
- data/lib/lurker/templates/lurker/rendering/show.html.erb +1 -37
- data/lib/lurker/templates/public/application.css +6 -2
- data/lib/lurker/templates/public/application.js +13 -13
- data/lib/lurker/templates/stylesheets/application.scss +3 -0
- data/lib/lurker/version.rb +1 -1
- data/lurker.gemspec +31 -33
- data/spec/spec_helper.rb +0 -1
- data/tasks/build.rake +12 -8
- data/tasks/generate.rake +44 -17
- data/templates/Dockerfile +26 -0
- data/templates/generate_stuff.rb +59 -26
- data/templates/lurker_app.rb +27 -48
- data/templates/rails4_ruby26_thread_error_fix.rb +20 -0
- metadata +149 -106
- checksums.yaml.gz.sig +0 -2
- data.tar.gz.sig +0 -3
- data/Appraisals +0 -20
- data/gemfiles/rails_32.gemfile +0 -27
- data/gemfiles/rails_40.gemfile +0 -27
- data/gemfiles/rails_41.gemfile +0 -27
- data/gemfiles/rails_42.gemfile +0 -27
- data/lib/lurker/templates/lurker/rendering/_param_form_legend.html.erb +0 -1
- data/lib/lurker/templates/meta_service.md.erb +0 -20
- data/lib/lurker/validation_error.rb +0 -4
- data/templates/rails32_http_patch_support.rb +0 -125
- metadata.gz.sig +0 -0
data/lib/lurker/endpoint.rb
CHANGED
@@ -19,7 +19,7 @@ module Lurker
|
|
19
19
|
RESPONSE_CODES = 'responseCodes'.freeze
|
20
20
|
REQUEST_PARAMETERS = 'requestParameters'.freeze
|
21
21
|
RESPONSE_PARAMETERS = 'responseParameters'.freeze
|
22
|
-
|
22
|
+
DESCRIPTIONS = {
|
23
23
|
'index' => 'listing',
|
24
24
|
'show' => '',
|
25
25
|
'edit' => 'editing',
|
@@ -44,7 +44,7 @@ module Lurker
|
|
44
44
|
finalize_schema!
|
45
45
|
|
46
46
|
Lurker::Json::Orderer.reorder(schema) unless persisted?
|
47
|
-
Lurker::Json::
|
47
|
+
Lurker::Json::Writer.write(schema, endpoint_path)
|
48
48
|
|
49
49
|
@persisted = true
|
50
50
|
end
|
@@ -131,6 +131,10 @@ module Lurker
|
|
131
131
|
@schema[RESPONSE_CODES]
|
132
132
|
end
|
133
133
|
|
134
|
+
def documentation
|
135
|
+
@schema.documentation
|
136
|
+
end
|
137
|
+
|
134
138
|
protected
|
135
139
|
|
136
140
|
def persisted?
|
@@ -167,7 +171,7 @@ module Lurker
|
|
167
171
|
def finalize_schema!
|
168
172
|
path_params = schema[EXTENSIONS][PATH_PARAMS] || {}
|
169
173
|
subject = path_params[CONTROLLER].to_s.split(/\//).last.to_s
|
170
|
-
description =
|
174
|
+
description = DESCRIPTIONS[path_params[ACTION]]
|
171
175
|
|
172
176
|
schema[DESCRIPTION] = "#{subject.singularize} #{description}".strip if schema[DESCRIPTION].blank?
|
173
177
|
schema[PREFIX] = "#{subject} management" if schema[PREFIX].blank?
|
@@ -188,15 +192,15 @@ module Lurker
|
|
188
192
|
def word_wrap(text)
|
189
193
|
# strip .json# | .json.yml# | .json.yml.erb#
|
190
194
|
text = text.reverse
|
191
|
-
text.gsub!(/(\n|^)#bre\./, "\nbre.")
|
192
|
-
text.gsub!(/(\n|^)#lmy\./, "\nlmy.")
|
193
|
-
text.gsub!(/(\n|^)#nosj\./, "\nnosj.")
|
195
|
+
text.gsub!(/(\n|^)#bre\./, "\nbre.") # erb
|
196
|
+
text.gsub!(/(\n|^)#lmy\./, "\nlmy.") # yml
|
197
|
+
text.gsub!(/(\n|^)#nosj\./, "\nnosj.") # json
|
194
198
|
text.strip!
|
195
199
|
text = text.reverse
|
196
200
|
|
197
201
|
text.gsub!(/\s+in schema/m, "\n in schema")
|
198
202
|
if defined?(Rails)
|
199
|
-
text.gsub!(
|
203
|
+
text.gsub!(Regexp.new("#{Rails.root}\/"), "")
|
200
204
|
end
|
201
205
|
text
|
202
206
|
end
|
data/lib/lurker/form_builder.rb
CHANGED
@@ -11,55 +11,46 @@ module Lurker
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
-
def add_to_buffer(params,
|
15
|
-
params.each do |
|
16
|
-
if parent_labels.present?
|
17
|
-
label = "[#{label}]"
|
18
|
-
end
|
19
|
-
|
20
|
-
new_parent_labels = parent_labels.clone << label
|
14
|
+
def add_to_buffer(params, parent_accessors = [])
|
15
|
+
params.each do |name, value|
|
21
16
|
|
17
|
+
accessors = parent_accessors.clone << name
|
22
18
|
if value.is_a?(Hash)
|
23
|
-
|
24
|
-
|
25
|
-
add_to_buffer(value, new_parent_labels)
|
19
|
+
add_to_buffer(value, accessors)
|
26
20
|
elsif value.is_a?(Array)
|
27
|
-
value.
|
21
|
+
value.each_with_index do |v, i|
|
28
22
|
if v.is_a?(Hash)
|
29
|
-
|
30
|
-
|
31
|
-
add_to_buffer(v, parent_labels.clone << "#{label}[]")
|
23
|
+
add_to_buffer(v, accessors << i)
|
32
24
|
else
|
33
|
-
add_element_to_buffer(
|
25
|
+
add_element_to_buffer(accessors, v)
|
34
26
|
end
|
35
27
|
end
|
36
28
|
else
|
37
|
-
add_element_to_buffer(
|
29
|
+
add_element_to_buffer(accessors, value)
|
38
30
|
end
|
39
31
|
end
|
40
32
|
end
|
41
33
|
|
42
|
-
def add_element_to_buffer(
|
34
|
+
def add_element_to_buffer(accessors, value)
|
43
35
|
@_buffer += render(
|
44
36
|
:partial => 'param_form_element',
|
45
|
-
:locals
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
37
|
+
:locals => {
|
38
|
+
:accessor => "#{accessors.compact.join('.')}",
|
39
|
+
:label => "#{print_labels(accessors)}",
|
40
|
+
:label_text => "#{print_labels(accessors)}",
|
41
|
+
:value => value
|
49
42
|
}
|
50
43
|
)
|
51
44
|
end
|
52
45
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
def print_labels(parent_labels)
|
62
|
-
"#{parent_labels * ''}"
|
46
|
+
def print_labels(accessors)
|
47
|
+
accessors.inject do |acc, label|
|
48
|
+
if label.is_a? Numeric
|
49
|
+
"#{acc}[]"
|
50
|
+
else
|
51
|
+
"#{acc}[#{label}]"
|
52
|
+
end
|
53
|
+
end
|
63
54
|
end
|
64
55
|
end
|
65
56
|
end
|
@@ -9,7 +9,11 @@ module Lurker
|
|
9
9
|
|
10
10
|
def to_validation_schema
|
11
11
|
set_additional_properties_false_on(to_hash).tap do |schema|
|
12
|
-
|
12
|
+
if uri.class == URI::Generic
|
13
|
+
schema[Json::ID] = uri.path
|
14
|
+
else
|
15
|
+
schema[Json::ID] = uri.to_s
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
data/lib/lurker/json/parser.rb
CHANGED
@@ -16,7 +16,7 @@ module Lurker
|
|
16
16
|
@parent_schema = options[:parent_schema]
|
17
17
|
@parent_property = options[:parent_property]
|
18
18
|
@polymorph_if_empty = options.fetch(:polymorph_if_empty, false)
|
19
|
-
@uri = options[:uri] || @parent_schema
|
19
|
+
@uri = options[:uri] || @parent_schema&.uri
|
20
20
|
@strategy = nil
|
21
21
|
end
|
22
22
|
|
data/lib/lurker/json/schema.rb
CHANGED
@@ -21,6 +21,16 @@ module Lurker
|
|
21
21
|
parse_schema(schema)
|
22
22
|
end
|
23
23
|
|
24
|
+
def documentation_uri(extension = 'md')
|
25
|
+
@uri.to_s.sub(%r{^file:(//)?}, '').sub(/(\.json)?(\.yml)?(\.erb)?$/, ".#{extension}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def documentation
|
29
|
+
open(documentation_uri).read
|
30
|
+
rescue
|
31
|
+
@schema['description']
|
32
|
+
end
|
33
|
+
|
24
34
|
def root?
|
25
35
|
root_schema.blank?
|
26
36
|
end
|
@@ -40,8 +50,7 @@ module Lurker
|
|
40
50
|
end
|
41
51
|
|
42
52
|
def replace!(property, property_schema)
|
43
|
-
@schema[property] =
|
44
|
-
.parse_property(property, property_schema)
|
53
|
+
@schema[property] = @parser.plain.parse_property(property, property_schema)
|
45
54
|
end
|
46
55
|
|
47
56
|
def reorder!
|
@@ -54,19 +63,23 @@ module Lurker
|
|
54
63
|
end
|
55
64
|
|
56
65
|
def to_json(options = {})
|
57
|
-
|
66
|
+
to_hash(options).to_json
|
58
67
|
end
|
59
68
|
|
60
69
|
def to_yaml(options = {})
|
61
70
|
YAML.dump(to_hash(options))
|
62
71
|
end
|
63
72
|
|
73
|
+
def respond_to_missing?(method, include_private=false)
|
74
|
+
@schema.respond_to?(method, include_private)
|
75
|
+
end
|
76
|
+
|
64
77
|
def method_missing(method, *args, &block)
|
65
78
|
if @schema.is_a?(Lurker::Json::Schema) || @schema.respond_to?(method)
|
66
|
-
|
79
|
+
@schema.send(method, *args, &block)
|
80
|
+
else
|
81
|
+
super
|
67
82
|
end
|
68
|
-
|
69
|
-
super
|
70
83
|
end
|
71
84
|
|
72
85
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Lurker
|
2
2
|
module Json
|
3
|
-
class
|
3
|
+
class Writer
|
4
4
|
class << self
|
5
5
|
def write(schema, path)
|
6
6
|
new(path).write(schema)
|
@@ -16,7 +16,7 @@ module Lurker
|
|
16
16
|
write_to_file(schema)
|
17
17
|
|
18
18
|
extract_references(schema).each do |reference|
|
19
|
-
Lurker::Json::
|
19
|
+
Lurker::Json::Writer.write(reference, reference.original_uri.path)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -9,16 +9,6 @@ class Lurker::BasePresenter
|
|
9
9
|
@options = options
|
10
10
|
end
|
11
11
|
|
12
|
-
def render_erb(erb_name, binding = get_binding)
|
13
|
-
template_path = path_for_template(erb_name)
|
14
|
-
template = ERB.new(File.read(template_path), nil, '-')
|
15
|
-
template.result(binding)
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_binding
|
19
|
-
binding
|
20
|
-
end
|
21
|
-
|
22
12
|
def html_directory
|
23
13
|
options[:url_base_path] || options[:html_directory] || ""
|
24
14
|
end
|
@@ -27,8 +17,12 @@ class Lurker::BasePresenter
|
|
27
17
|
options[:url_base_path] || '/'
|
28
18
|
end
|
29
19
|
|
30
|
-
def
|
31
|
-
|
20
|
+
def assets
|
21
|
+
options[:assets] || {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def asset_path(asset)
|
25
|
+
"#{html_directory}/#{assets[asset] || asset}"
|
32
26
|
end
|
33
27
|
|
34
28
|
def index_path(subdirectory = "")
|
@@ -51,27 +45,9 @@ class Lurker::BasePresenter
|
|
51
45
|
EOS
|
52
46
|
end
|
53
47
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
protected
|
59
|
-
|
60
|
-
def path_for_template(filename)
|
61
|
-
template_dir = options[:template_directory]
|
62
|
-
template_path = File.join(template_dir, filename) if template_dir
|
63
|
-
if template_path.nil? || !File.exist?(template_path)
|
64
|
-
template_path = File.join(File.dirname(__FILE__), "../templates", filename)
|
65
|
-
end
|
66
|
-
template_path
|
67
|
-
end
|
68
|
-
|
69
|
-
def rendering_controller
|
70
|
-
return @rendering_controller if @rendering_controller
|
71
|
-
@rendering_controller = Lurker::RenderingController.new
|
72
|
-
instance_variables.each do |var|
|
73
|
-
@rendering_controller.instance_variable_set(var, instance_variable_get(var))
|
74
|
-
end
|
75
|
-
@rendering_controller
|
48
|
+
def markup(content)
|
49
|
+
return unless content
|
50
|
+
Lurker.safe_require 'kramdown'
|
51
|
+
defined?(Kramdown) ? Kramdown::Document.new(content).to_html : content
|
76
52
|
end
|
77
53
|
end
|
@@ -2,6 +2,9 @@
|
|
2
2
|
class Lurker::EndpointPresenter < Lurker::BasePresenter
|
3
3
|
attr_accessor :service_presenter, :endpoint, :endpoint_presenter
|
4
4
|
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :endpoint, :url_params
|
7
|
+
|
5
8
|
def initialize(endpoint, options = {})
|
6
9
|
super(options)
|
7
10
|
@endpoint = endpoint
|
@@ -10,11 +13,15 @@ class Lurker::EndpointPresenter < Lurker::BasePresenter
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def to_html(options={})
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
controller = Lurker::RenderingController.new
|
17
|
+
controller.service_presenter = service_presenter
|
18
|
+
controller.endpoint_presenter = self
|
19
|
+
controller.instance_variable_set :@title, "#{service_presenter.title} | #{title}"
|
20
|
+
controller.render_to_string 'show', options
|
21
|
+
end
|
22
|
+
|
23
|
+
def documentation
|
24
|
+
markup @endpoint.documentation
|
18
25
|
end
|
19
26
|
|
20
27
|
def relative_path(extension = ".html")
|
@@ -33,6 +40,10 @@ class Lurker::EndpointPresenter < Lurker::BasePresenter
|
|
33
40
|
endpoint.prefix || endpoint.path.split("/").first
|
34
41
|
end
|
35
42
|
|
43
|
+
def post_params
|
44
|
+
example_request.json
|
45
|
+
end
|
46
|
+
|
36
47
|
def zws_ify(str)
|
37
48
|
# zero-width-space, makes long lines friendlier for breaking
|
38
49
|
# str.gsub(/\//, '​/') if str
|
@@ -209,15 +220,15 @@ class Lurker::EndpointPresenter < Lurker::BasePresenter
|
|
209
220
|
end
|
210
221
|
|
211
222
|
def example_from_array(array, parent=nil)
|
212
|
-
if array["items"].
|
223
|
+
if array["items"].respond_to?(:each) && !array["items"].respond_to?(:each_pair)
|
213
224
|
example = []
|
214
225
|
array["items"].each do |item|
|
215
226
|
example << example_from_schema(item, parent)
|
216
227
|
end
|
217
228
|
example
|
218
|
-
elsif (array["items"] || {})["type"].
|
229
|
+
elsif (types = (array["items"] || {})["type"]).respond_to?(:each)
|
219
230
|
example = []
|
220
|
-
|
231
|
+
types.each do |item|
|
221
232
|
example << example_from_schema(item, parent)
|
222
233
|
end
|
223
234
|
example
|
@@ -116,18 +116,19 @@ class Lurker::SchemaPresenter < Lurker::BasePresenter
|
|
116
116
|
|
117
117
|
def items_html
|
118
118
|
return unless items = @schema["items"]
|
119
|
+
return if items.size == 0
|
119
120
|
|
120
121
|
html = ""
|
121
122
|
html << '<li>Items'
|
122
123
|
|
123
124
|
sub_options = options.merge(:nested => options[:nested] + 1, :parent => self)
|
124
125
|
|
125
|
-
if items.
|
126
|
-
item.compact.each do |item|
|
127
|
-
html << self.class.new(item, sub_options).to_html
|
128
|
-
end
|
129
|
-
else
|
126
|
+
if items.respond_to?(:each_pair)
|
130
127
|
html << self.class.new(items, sub_options).to_html
|
128
|
+
else
|
129
|
+
items.each do |item|
|
130
|
+
html << self.class.new(item, sub_options).to_html if item
|
131
|
+
end
|
131
132
|
end
|
132
133
|
|
133
134
|
html << '</li>'
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require 'active_support/hash_with_indifferent_access'
|
3
|
+
|
1
4
|
# An BasePresenter for Lurker::Service
|
2
5
|
class Lurker::ServicePresenter < Lurker::BasePresenter
|
3
6
|
attr_reader :service
|
@@ -11,14 +14,24 @@ class Lurker::ServicePresenter < Lurker::BasePresenter
|
|
11
14
|
@filtering_block = block
|
12
15
|
end
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
def to_html(options={}, &block)
|
18
|
+
controller = Lurker::RenderingController.new
|
19
|
+
controller.service_presenter = self
|
20
|
+
controller.render_to_string 'index', options
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_print(options = {})
|
24
|
+
controller = Lurker::RenderingController.new
|
25
|
+
controller.service_presenter = self
|
26
|
+
controller.render_to_string 'all', { layout: 'print' }.merge(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def documentation
|
30
|
+
markup @service.documentation
|
18
31
|
end
|
19
32
|
|
20
33
|
def title
|
21
|
-
"
|
34
|
+
"#{name}"
|
22
35
|
end
|
23
36
|
|
24
37
|
def domains
|
@@ -31,19 +44,40 @@ class Lurker::ServicePresenter < Lurker::BasePresenter
|
|
31
44
|
'/'
|
32
45
|
end
|
33
46
|
|
47
|
+
def request_media_types
|
48
|
+
return service.request_media_types if service.request_media_types.present?
|
49
|
+
['application/x-www-form-urlencoded']
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_request_media_type
|
53
|
+
request_media_types[0]
|
54
|
+
end
|
55
|
+
|
34
56
|
def name_as_link(options = {})
|
35
57
|
path = index_path
|
36
58
|
'<a href="%s">%s %s</a>' % [path, options[:prefix], service.name]
|
37
59
|
end
|
38
60
|
|
39
61
|
def slug_name
|
40
|
-
service.name.downcase.gsub(/[ \/]/, '_')
|
62
|
+
@slug_name ||= service.name.downcase.gsub(/[ \/]/, '_')
|
63
|
+
end
|
64
|
+
|
65
|
+
def url_name
|
66
|
+
@url_name ||= name.gsub(/[^a-z0-9\-_]+/i, '_')
|
41
67
|
end
|
42
68
|
|
43
69
|
def url(extension = ".html")
|
44
70
|
'%s-%s%s' % [@endpoint.path, @endpoint.verb, extension]
|
45
71
|
end
|
46
72
|
|
73
|
+
def footer
|
74
|
+
@footer ||= options[:footer].present? ? "Revision #{options[:footer]}".html_safe : ''
|
75
|
+
end
|
76
|
+
|
77
|
+
def lurker
|
78
|
+
@lurker ||= options[:lurker] || ''
|
79
|
+
end
|
80
|
+
|
47
81
|
def endpoints
|
48
82
|
unless @endpoints
|
49
83
|
@endpoints = []
|
@@ -91,6 +125,6 @@ class Lurker::ServicePresenter < Lurker::BasePresenter
|
|
91
125
|
private
|
92
126
|
|
93
127
|
def service_domains
|
94
|
-
service.domains.to_hash
|
128
|
+
service.domains.try(:to_hash) || {}
|
95
129
|
end
|
96
130
|
end
|