shaf 1.6.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/iana_link_relations.csv.gz +0 -0
- data/lib/shaf.rb +6 -0
- data/lib/shaf/alps/attribute_serializer.rb +41 -0
- data/lib/shaf/alps/json_serializer.rb +50 -0
- data/lib/shaf/alps/relation_serializer.rb +70 -0
- data/lib/shaf/api_doc/link_relations.rb +77 -0
- data/lib/shaf/authenticator.rb +56 -0
- data/lib/shaf/authenticator/base.rb +161 -0
- data/lib/shaf/authenticator/basic_auth.rb +25 -0
- data/lib/shaf/authenticator/challenge.rb +32 -0
- data/lib/shaf/authenticator/parameter.rb +31 -0
- data/lib/shaf/authenticator/request.rb +17 -0
- data/lib/shaf/command/console.rb +1 -1
- data/lib/shaf/command/generate.rb +5 -2
- data/lib/shaf/command/new.rb +20 -7
- data/lib/shaf/command/templates/Gemfile.erb +1 -0
- data/{templates/config/settings.yml → lib/shaf/command/templates/config/settings.yml.erb} +1 -5
- data/lib/shaf/errors.rb +11 -0
- data/lib/shaf/extensions.rb +3 -3
- data/lib/shaf/extensions/api_routes.rb +60 -0
- data/lib/shaf/extensions/authorize.rb +11 -9
- data/lib/shaf/extensions/log.rb +1 -1
- data/lib/shaf/extensions/resource_uris.rb +139 -63
- data/lib/shaf/extensions/symbolic_routes.rb +22 -19
- data/lib/shaf/formable.rb +1 -2
- data/lib/shaf/formable/form.rb +1 -1
- data/lib/shaf/generator.rb +2 -0
- data/lib/shaf/generator/base.rb +2 -3
- data/lib/shaf/generator/controller.rb +11 -7
- data/lib/shaf/generator/doc.rb +17 -0
- data/lib/shaf/generator/forms.rb +1 -0
- data/lib/shaf/generator/helper.rb +2 -1
- data/lib/shaf/generator/migration/base.rb +7 -3
- data/lib/shaf/generator/migration/type.rb +4 -26
- data/lib/shaf/generator/migration/types.rb +45 -16
- data/lib/shaf/generator/model.rb +1 -2
- data/lib/shaf/generator/profile.rb +52 -0
- data/lib/shaf/generator/serializer.rb +38 -73
- data/lib/shaf/generator/templates/api/policy.rb.erb +2 -2
- data/lib/shaf/generator/templates/api/profile.rb.erb +16 -0
- data/lib/shaf/generator/templates/api/serializer.rb.erb +2 -2
- data/lib/shaf/generator/templates/spec/integration_spec.rb.erb +1 -2
- data/lib/shaf/generator/templates/spec/serializer_spec.rb.erb +5 -5
- data/lib/shaf/helpers.rb +4 -0
- data/lib/shaf/helpers/authentication.rb +79 -0
- data/lib/shaf/helpers/payload.rb +14 -34
- data/lib/shaf/helpers/vary.rb +8 -0
- data/lib/shaf/logger.rb +12 -0
- data/lib/shaf/parser.rb +65 -0
- data/lib/shaf/parser/base.rb +44 -0
- data/lib/shaf/parser/form_data.rb +15 -0
- data/lib/shaf/parser/json.rb +26 -0
- data/lib/shaf/profile.rb +110 -0
- data/lib/shaf/profile/attribute.rb +29 -0
- data/lib/shaf/profile/evaluator.rb +46 -0
- data/lib/shaf/profile/relation.rb +29 -0
- data/lib/shaf/profile/unique_id.rb +58 -0
- data/lib/shaf/profiles.rb +42 -0
- data/lib/shaf/profiles/shaf_basic.rb +20 -0
- data/lib/shaf/profiles/shaf_error.rb +48 -0
- data/lib/shaf/profiles/shaf_form.rb +109 -0
- data/lib/shaf/responder.rb +41 -2
- data/lib/shaf/responder/alps_json.rb +25 -0
- data/lib/shaf/responder/base.rb +20 -17
- data/lib/shaf/responder/hal.rb +65 -4
- data/lib/shaf/responder/html.rb +43 -16
- data/lib/shaf/responder/problem_json.rb +1 -1
- data/lib/shaf/serializer.rb +31 -0
- data/lib/shaf/settings.rb +25 -12
- data/lib/shaf/spec.rb +1 -0
- data/lib/shaf/spec/authenticator.rb +13 -0
- data/lib/shaf/spec/base.rb +1 -1
- data/lib/shaf/spec/http_method_utils.rb +1 -1
- data/lib/shaf/spec/integration_spec.rb +25 -13
- data/lib/shaf/spec/payload_utils.rb +2 -2
- data/lib/shaf/supported_http_methods.rb +15 -0
- data/lib/shaf/tasks/api_doc_task.rb +24 -3
- data/lib/shaf/tasks/routes_task.rb +14 -17
- data/lib/shaf/upgrade/manifest.rb +11 -2
- data/lib/shaf/upgrade/package.rb +73 -43
- data/lib/shaf/upgrade/version.rb +11 -10
- data/lib/shaf/utils.rb +19 -5
- data/lib/shaf/version.rb +3 -1
- data/lib/shaf/yard.rb +34 -0
- data/lib/shaf/yard/attribute_method_handler.rb +19 -0
- data/lib/shaf/yard/attribute_object.rb +30 -0
- data/lib/shaf/yard/base_method_handler.rb +30 -0
- data/lib/shaf/yard/link_method_handler.rb +39 -0
- data/lib/shaf/yard/link_object.rb +60 -0
- data/lib/shaf/yard/nested_attributes.rb +37 -0
- data/lib/shaf/yard/parser.rb +64 -0
- data/lib/shaf/yard/profile_method_handler.rb +51 -0
- data/lib/shaf/yard/profile_object.rb +21 -0
- data/lib/shaf/yard/resource_object.rb +55 -0
- data/lib/shaf/yard/serializer_handler.rb +27 -0
- data/templates/api/controllers/base_controller.rb +0 -10
- data/templates/api/controllers/docs_controller.rb +5 -3
- data/templates/api/controllers/root_controller.rb +7 -1
- data/templates/api/policies/base_policy.rb +2 -0
- data/templates/api/serializers/base_serializer.rb +1 -3
- data/templates/api/serializers/error_serializer.rb +1 -5
- data/templates/api/serializers/form_serializer.rb +1 -5
- data/templates/api/serializers/validation_error_serializer.rb +1 -5
- data/templates/config/bootstrap.rb +1 -2
- data/templates/config/directories.rb +52 -44
- data/templates/config/helpers.rb +1 -1
- data/templates/config/initializers.rb +52 -8
- data/templates/config/initializers/authentication.rb +18 -0
- data/templates/config/initializers/db_migrations.rb +2 -2
- data/templates/config/initializers/logging.rb +2 -2
- data/templates/spec/spec_helper.rb +2 -0
- data/upgrades/0.5.0.tar.gz +0 -0
- data/upgrades/1.0.4.tar.gz +0 -0
- data/upgrades/1.1.0.tar.gz +0 -0
- data/upgrades/2.0.0.tar.gz +0 -0
- data/yard_templates/api_doc/doc_index/html/body.erb +3 -0
- data/yard_templates/api_doc/doc_index/setup.rb +8 -0
- data/yard_templates/api_doc/html/css/api-doc.css +222 -0
- data/yard_templates/api_doc/html/favicon.ico +0 -0
- data/yard_templates/api_doc/html/js/switch_tab.js +17 -0
- data/yard_templates/api_doc/html/setup.rb +59 -0
- data/yard_templates/api_doc/layout/html/footer.erb +3 -0
- data/yard_templates/api_doc/layout/html/header.erb +7 -0
- data/yard_templates/api_doc/layout/html/layout.erb +13 -0
- data/yard_templates/api_doc/layout/setup.rb +24 -0
- data/yard_templates/api_doc/profile/html/attributes.erb +10 -0
- data/yard_templates/api_doc/profile/html/profile.erb +6 -0
- data/yard_templates/api_doc/profile/html/relations.erb +10 -0
- data/yard_templates/api_doc/profile/setup.rb +38 -0
- data/yard_templates/api_doc/profile_attribute/html/attribute.erb +23 -0
- data/yard_templates/api_doc/profile_attribute/setup.rb +21 -0
- data/yard_templates/api_doc/profile_relation/html/relation.erb +37 -0
- data/yard_templates/api_doc/profile_relation/setup.rb +41 -0
- data/yard_templates/api_doc/resource/html/attributes.erb +10 -0
- data/yard_templates/api_doc/resource/html/profile.erb +14 -0
- data/yard_templates/api_doc/resource/html/relations.erb +10 -0
- data/yard_templates/api_doc/resource/html/resource.erb +5 -0
- data/yard_templates/api_doc/resource/setup.rb +56 -0
- data/yard_templates/api_doc/resource_attribute/html/attribute.erb +23 -0
- data/yard_templates/api_doc/resource_attribute/setup.rb +20 -0
- data/yard_templates/api_doc/resource_relation/html/relation.erb +47 -0
- data/yard_templates/api_doc/resource_relation/setup.rb +80 -0
- data/yard_templates/api_doc/setup.rb +31 -0
- data/yard_templates/api_doc/sidebar/html/profile_list.erb +8 -0
- data/yard_templates/api_doc/sidebar/html/search.erb +7 -0
- data/yard_templates/api_doc/sidebar/html/serializer_list.erb +8 -0
- data/yard_templates/api_doc/sidebar/html/sidebar.erb +13 -0
- data/yard_templates/api_doc/sidebar/setup.rb +56 -0
- metadata +137 -30
- metadata.gz.sig +1 -3
- data/lib/shaf/extensions/current_user.rb +0 -48
- data/lib/shaf/responder/hal_serializable.rb +0 -64
data/lib/shaf/responder.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'shaf/errors'
|
2
3
|
|
3
4
|
module Shaf
|
4
5
|
module Responder
|
6
|
+
MEDIA_TYPE_SUFFIX_PATTERN = %r{(.*)/([^+]+)\+(.*)}.freeze
|
7
|
+
|
5
8
|
class << self
|
6
9
|
def register(responder)
|
7
10
|
uninitialized << responder
|
@@ -15,15 +18,23 @@ module Shaf
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def for(request, resource)
|
21
|
+
return Responder::ProblemJson if resource.is_a?(Errors::NotAcceptableError)
|
22
|
+
|
18
23
|
types = supported_responders_for(resource).map(&:mime_type)
|
19
|
-
|
20
|
-
|
24
|
+
types = move_html_to_last(types)
|
25
|
+
|
26
|
+
mime = preferred_type(request, types)
|
27
|
+
responders[mime] or raise Errors::NotAcceptableError
|
21
28
|
end
|
22
29
|
|
23
30
|
def default=(responder)
|
24
31
|
responders.default = responder
|
25
32
|
end
|
26
33
|
|
34
|
+
def default
|
35
|
+
responders.default
|
36
|
+
end
|
37
|
+
|
27
38
|
private
|
28
39
|
|
29
40
|
def supported_responders_for(resource)
|
@@ -41,6 +52,23 @@ module Shaf
|
|
41
52
|
@supported_responders ||= Hash.new { |hash, key| hash[key] = Set.new }
|
42
53
|
end
|
43
54
|
|
55
|
+
def preferred_type(request, types)
|
56
|
+
mime = request.preferred_type(types)
|
57
|
+
return mime if mime
|
58
|
+
|
59
|
+
request.accept.find do |accept|
|
60
|
+
next if accept.match? MEDIA_TYPE_SUFFIX_PATTERN
|
61
|
+
|
62
|
+
types.find do |type|
|
63
|
+
m = type.match MEDIA_TYPE_SUFFIX_PATTERN
|
64
|
+
next unless m
|
65
|
+
|
66
|
+
format = "#{m[1]}/#{m[3]}"
|
67
|
+
return type if accept.to_str == format
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
44
72
|
def uninitialized
|
45
73
|
@uninitialized ||= []
|
46
74
|
end
|
@@ -57,6 +85,16 @@ module Shaf
|
|
57
85
|
init_responders!
|
58
86
|
end
|
59
87
|
end
|
88
|
+
|
89
|
+
# We want to always be able to respond with text/html, but only when
|
90
|
+
# asked for (Accept header) to be able to let other more specific mime
|
91
|
+
# types take precedence we need to move text/html to the end of the
|
92
|
+
# array.
|
93
|
+
def move_html_to_last(types)
|
94
|
+
return types unless types.include? Html.mime_type
|
95
|
+
|
96
|
+
(types - [Html.mime_type]) << Html.mime_type
|
97
|
+
end
|
60
98
|
end
|
61
99
|
end
|
62
100
|
end
|
@@ -65,3 +103,4 @@ require 'shaf/responder/base'
|
|
65
103
|
require 'shaf/responder/hal'
|
66
104
|
require 'shaf/responder/html'
|
67
105
|
require 'shaf/responder/problem_json'
|
106
|
+
require 'shaf/responder/alps_json'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'shaf/alps/json_serializer'
|
2
|
+
|
3
|
+
module Shaf
|
4
|
+
module Responder
|
5
|
+
class AlpsJson < Base
|
6
|
+
mime_type :alps_json, 'application/alps+json'
|
7
|
+
|
8
|
+
def self.can_handle?(resource)
|
9
|
+
return false unless resource.is_a? Class
|
10
|
+
resource <= Shaf::Profile
|
11
|
+
end
|
12
|
+
|
13
|
+
def body
|
14
|
+
JSON.generate hash
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def hash
|
20
|
+
ALPS::JsonSerializer.call(resource)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/shaf/responder/base.rb
CHANGED
@@ -2,12 +2,14 @@ module Shaf
|
|
2
2
|
module Responder
|
3
3
|
class Response
|
4
4
|
attr_reader :content_type, :body, :serialized_hash, :resource
|
5
|
+
attr_accessor :preload_links
|
5
6
|
|
6
7
|
def initialize(content_type:, body:, serialized_hash: {}, resource: nil)
|
7
8
|
@content_type = content_type
|
8
9
|
@body = body
|
9
10
|
@serialized_hash = serialized_hash
|
10
11
|
@resource = resource
|
12
|
+
@preload_links = []
|
11
13
|
end
|
12
14
|
|
13
15
|
def log_entry
|
@@ -36,11 +38,10 @@ module Shaf
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def call(controller, resource, preload: [], **kwargs)
|
39
|
-
responder = new(controller, resource, **kwargs)
|
41
|
+
responder = new(controller, resource, preload_rels: preload, **kwargs)
|
40
42
|
response = responder.build_response
|
41
43
|
log_response(controller, response)
|
42
|
-
|
43
|
-
write_response(controller, response, preload_links)
|
44
|
+
write_response(controller, response)
|
44
45
|
end
|
45
46
|
|
46
47
|
def can_handle?(_obj)
|
@@ -58,23 +59,14 @@ module Shaf
|
|
58
59
|
controller.log.send(type, msg)
|
59
60
|
end
|
60
61
|
|
61
|
-
def
|
62
|
-
Array(rels).map do |rel|
|
63
|
-
links = responder.lookup_rel(rel, response)
|
64
|
-
links = [links].compact unless links.is_a? Array
|
65
|
-
log(controller, PRELOAD_FAILED_MSG % rel) if links.empty?
|
66
|
-
links
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def write_response(controller, response, preload_links)
|
62
|
+
def write_response(controller, response)
|
71
63
|
controller.content_type(response.content_type)
|
72
|
-
add_preload_links(controller, response
|
64
|
+
add_preload_links(controller, response)
|
73
65
|
controller.body(response.body)
|
74
66
|
end
|
75
67
|
|
76
|
-
def add_preload_links(controller, response
|
77
|
-
preload_links.each do |links|
|
68
|
+
def add_preload_links(controller, response)
|
69
|
+
response.preload_links.each do |links|
|
78
70
|
links.each do |link|
|
79
71
|
next unless link[:href]
|
80
72
|
# Nginx http2_push_preload only processes relative URIs with absolute path
|
@@ -111,9 +103,20 @@ module Shaf
|
|
111
103
|
body: body,
|
112
104
|
serialized_hash: serialized_hash,
|
113
105
|
resource: resource
|
114
|
-
)
|
106
|
+
).tap do |response|
|
107
|
+
response.preload_links = preload_links(response)
|
108
|
+
end
|
115
109
|
end
|
116
110
|
|
111
|
+
def preload_links(response)
|
112
|
+
Array(options[:preload_rels]).map do |rel|
|
113
|
+
links = lookup_rel(rel, response)
|
114
|
+
links = [links].compact unless links.is_a? Array
|
115
|
+
log(controller, PRELOAD_FAILED_MSG % rel) if links.empty?
|
116
|
+
links
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
117
120
|
def lookup_rel(_rel, _response)
|
118
121
|
[]
|
119
122
|
end
|
data/lib/shaf/responder/hal.rb
CHANGED
@@ -1,17 +1,37 @@
|
|
1
|
-
require 'shaf/responder/hal_serializable'
|
2
|
-
|
3
1
|
module Shaf
|
4
2
|
module Responder
|
5
3
|
class Hal < Base
|
6
|
-
include HalSerializable
|
7
|
-
|
8
4
|
use_as_default!
|
9
5
|
mime_type :hal, 'application/hal+json'
|
10
6
|
|
7
|
+
def self.can_handle?(resource)
|
8
|
+
return false if resource.is_a? StandardError
|
9
|
+
|
10
|
+
if resource.is_a? Class
|
11
|
+
return false if resource <= Shaf::Profile
|
12
|
+
end
|
13
|
+
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
11
17
|
def body
|
12
18
|
@body ||= generate_json
|
13
19
|
end
|
14
20
|
|
21
|
+
def lookup_rel(rel, response)
|
22
|
+
hal = response.serialized_hash
|
23
|
+
links = hal&.dig(:_links, rel.to_sym)
|
24
|
+
return [] unless links
|
25
|
+
|
26
|
+
links = [links] unless links.is_a? Array
|
27
|
+
links.map do |link|
|
28
|
+
{
|
29
|
+
href: link[:href],
|
30
|
+
as: 'fetch',
|
31
|
+
crossorigin: 'anonymous'
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
15
35
|
private
|
16
36
|
|
17
37
|
def mime_type
|
@@ -19,6 +39,47 @@ module Shaf
|
|
19
39
|
type = "#{type};profile=#{profile}" if profile
|
20
40
|
type
|
21
41
|
end
|
42
|
+
|
43
|
+
def collection?
|
44
|
+
!!options.fetch(:collection, false)
|
45
|
+
end
|
46
|
+
|
47
|
+
def serializer
|
48
|
+
@serializer ||= options[:serializer] || HALPresenter.lookup_presenter(resource)
|
49
|
+
end
|
50
|
+
|
51
|
+
def serialized_hash
|
52
|
+
raise Errors::NotAcceptableError unless serializer
|
53
|
+
|
54
|
+
@serialized_hash ||=
|
55
|
+
if collection?
|
56
|
+
serializer.to_collection(resource, current_user: user, as_hash: true, **options)
|
57
|
+
else
|
58
|
+
serializer.to_hal(resource, current_user: user, as_hash: true, **options)
|
59
|
+
end
|
60
|
+
|
61
|
+
# hal_presenter versions before v1.5.0 does not understand the :as_hash
|
62
|
+
# keyword argument and will always return a String from
|
63
|
+
# to_hal/to_collection, thus we need to parse it if its a String.
|
64
|
+
if @serialized_hash.is_a? String
|
65
|
+
@body = @serialized_hash
|
66
|
+
@serialized_hash = JSON.parse(@serialized_hash, symbolize_names: true)
|
67
|
+
end
|
68
|
+
|
69
|
+
@serialized_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
def profile
|
73
|
+
@profile ||= options[:profile]
|
74
|
+
return unless @profile || serializer
|
75
|
+
|
76
|
+
@profile ||= serializer.semantic_profile
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_json
|
80
|
+
# FIXME: change to Oj??
|
81
|
+
JSON.generate(serialized_hash)
|
82
|
+
end
|
22
83
|
end
|
23
84
|
end
|
24
85
|
end
|
data/lib/shaf/responder/html.rb
CHANGED
@@ -1,14 +1,50 @@
|
|
1
|
-
require 'shaf/responder/hal_serializable'
|
2
|
-
|
3
1
|
module Shaf
|
4
2
|
module Responder
|
5
3
|
class Html < Base
|
6
|
-
include HalSerializable
|
7
|
-
|
8
4
|
mime_type :html
|
9
5
|
|
6
|
+
class << self
|
7
|
+
def call(controller, resource, preload: [], **kwargs)
|
8
|
+
responder = responder_for(resource, controller, preload_rels: preload, **kwargs)
|
9
|
+
response = responder.build_response
|
10
|
+
add_preload_links(controller, response)
|
11
|
+
|
12
|
+
html_responder = new(controller, resource, response: response)
|
13
|
+
html_response = html_responder.build_response
|
14
|
+
log_response(controller, response)
|
15
|
+
|
16
|
+
write_response(controller, html_response)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Returns the "original" (non-html) responder
|
21
|
+
def responder_for(resource, controller, **kwargs)
|
22
|
+
responders = Responder.send(:supported_responders_for, resource)
|
23
|
+
responder_class = (responders - [self]).first || Responder.default
|
24
|
+
responder_class.new(controller, resource, **kwargs)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
10
28
|
def body
|
11
|
-
|
29
|
+
response = options[:response]
|
30
|
+
serialized = response.serialized_hash
|
31
|
+
if serialized.empty?
|
32
|
+
serialized = begin
|
33
|
+
JSON.parse(response.body)
|
34
|
+
rescue StandardError
|
35
|
+
response.body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
render serialized
|
40
|
+
end
|
41
|
+
|
42
|
+
def render(serialized)
|
43
|
+
locals = {
|
44
|
+
request_headers: request_headers,
|
45
|
+
response_headers: response_headers,
|
46
|
+
serialized: serialized
|
47
|
+
}
|
12
48
|
|
13
49
|
template =
|
14
50
|
case resource
|
@@ -22,25 +58,16 @@ module Shaf
|
|
22
58
|
controller.erb(template, locals: locals)
|
23
59
|
end
|
24
60
|
|
25
|
-
def variables
|
26
|
-
{
|
27
|
-
request_headers: request_headers,
|
28
|
-
response_headers: response_headers,
|
29
|
-
serialized: serialized_hash
|
30
|
-
}
|
31
|
-
end
|
32
|
-
|
33
61
|
def request_headers
|
34
62
|
controller.request_headers
|
35
63
|
end
|
36
64
|
|
37
65
|
def response_headers
|
38
|
-
etag, kind = controller.send(:etag_for,
|
66
|
+
etag, kind = controller.send(:etag_for, options[:response].body)
|
39
67
|
prefix = kind == :weak ? 'W/' : ''
|
40
68
|
etag = %Q{#{prefix}"#{etag}"}
|
41
69
|
|
42
|
-
type =
|
43
|
-
type = "#{type};profile=#{profile}" if profile
|
70
|
+
type = options[:response].content_type
|
44
71
|
|
45
72
|
controller.headers.merge('Content-Type' => type, 'ETag' => etag)
|
46
73
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hal_presenter'
|
4
|
+
|
5
|
+
module Shaf
|
6
|
+
# A base class used for serializing objects into a HAL representations.
|
7
|
+
class Serializer
|
8
|
+
extend HALPresenter
|
9
|
+
extend UriHelper
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :default_curie_prefix
|
13
|
+
|
14
|
+
# Creates a link with rel profile and href pointing to the corresponding profile.
|
15
|
+
# It also adds a Curie link.
|
16
|
+
# @param name [String] the name of the profile
|
17
|
+
# @param curie_prefix [Symbol] the prefix used for the Curie
|
18
|
+
def profile(name, curie_prefix: :doc)
|
19
|
+
link :profile do
|
20
|
+
profile_uri(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
curie curie_prefix do
|
24
|
+
doc_curie_uri(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
@default_curie_prefix = curie_prefix.to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/shaf/settings.rb
CHANGED
@@ -12,24 +12,41 @@ module Shaf
|
|
12
12
|
documents_dir: 'doc/api',
|
13
13
|
migrations_dir: 'db/migrations',
|
14
14
|
fixtures_dir: 'spec/fixtures',
|
15
|
-
auth_token_header: 'X-Auth-Token',
|
16
15
|
paginate_per_page: 25
|
17
16
|
}.freeze
|
18
17
|
|
19
18
|
class << self
|
20
|
-
def
|
21
|
-
|
22
|
-
config = Utils.read_config(SETTINGS_FILE, erb: true)
|
23
|
-
@settings.merge! config.fetch(env, {})
|
19
|
+
def env
|
20
|
+
(ENV['APP_ENV'] || ENV['RACK_ENV'] || 'development').to_sym
|
24
21
|
end
|
25
22
|
|
23
|
+
def key?(key)
|
24
|
+
settings.key? key
|
25
|
+
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def to_h
|
28
|
+
settings.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def loaded?
|
32
|
+
!!defined? @settings
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def settings
|
38
|
+
load_config unless loaded?
|
39
|
+
@settings
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_config
|
43
|
+
@settings = DEFAULTS.dup
|
44
|
+
config = Utils.read_config(SETTINGS_FILE, erb: true)
|
45
|
+
@settings.merge! config.fetch(env, {})
|
29
46
|
end
|
30
47
|
|
31
48
|
def method_missing(method, *args)
|
32
|
-
|
49
|
+
load_config unless loaded?
|
33
50
|
|
34
51
|
if method.to_s.end_with? '='
|
35
52
|
define_setter(method)
|
@@ -56,10 +73,6 @@ module Shaf
|
|
56
73
|
@settings[key] = arg
|
57
74
|
end
|
58
75
|
end
|
59
|
-
|
60
|
-
def to_h
|
61
|
-
@settings.dup
|
62
|
-
end
|
63
76
|
end
|
64
77
|
end
|
65
78
|
end
|