media_types-serialization 1.3.8 → 1.3.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/lib/media_types/problem.rb +7 -4
- data/lib/media_types/serialization/serializers/api_viewer.rb +22 -19
- data/lib/media_types/serialization/serializers/common_css.rb +24 -24
- data/lib/media_types/serialization/serializers/input_validation_error_serializer.rb +18 -14
- data/lib/media_types/serialization/serializers/problem_serializer.rb +8 -4
- data/lib/media_types/serialization/version.rb +2 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64e776b0385e75bc7accfd536320105d6f54724f5b85f10ce8396c412e3d42f4
|
4
|
+
data.tar.gz: fcac17f274d2f295d4ca57f20375caa7c54baf5cad1c8300a65416e5172bf2ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60a7cfd98fd87f4b5ca3facb3338518015abb4567b5ff35741a16e7b36bd4bb58a2262dd74c34c884d119d5844c2cf1034e2f4ac566dfee6205e2797ad730c4a
|
7
|
+
data.tar.gz: 1911cb60916f41d1ce594d7b98ed072cce91092bf6c00f60ae985fe50cc5380ef7367b0bff5a9d0f72f0f83a5b7a9072708ebccd81096c539a04c88603f0fc37
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/lib/media_types/problem.rb
CHANGED
@@ -4,7 +4,6 @@ require 'erb'
|
|
4
4
|
|
5
5
|
module MediaTypes
|
6
6
|
class Problem
|
7
|
-
|
8
7
|
def initialize(error)
|
9
8
|
self.error = error
|
10
9
|
self.translations = {}
|
@@ -17,7 +16,7 @@ module MediaTypes
|
|
17
16
|
def type
|
18
17
|
return custom_type unless custom_type.nil?
|
19
18
|
|
20
|
-
"https://docs.delftsolutions.nl/wiki/Error/#{ERB::Util
|
19
|
+
"https://docs.delftsolutions.nl/wiki/Error/#{ERB::Util.url_encode(error.class.name)}"
|
21
20
|
end
|
22
21
|
|
23
22
|
def url(href)
|
@@ -31,13 +30,17 @@ module MediaTypes
|
|
31
30
|
|
32
31
|
def override_detail(detail, lang:)
|
33
32
|
raise 'Unable to override detail message without having a title in the same language.' unless translations[lang]
|
33
|
+
|
34
34
|
translations[lang][:detail] = detail
|
35
35
|
end
|
36
36
|
|
37
37
|
def attribute(name, value)
|
38
38
|
str_name = name.to_s
|
39
39
|
|
40
|
-
|
40
|
+
unless str_name =~ /^[a-zA-Z][a-zA-Z0-9_]{2,}$/
|
41
|
+
raise "Unable to add an attribute with name '#{str_name}'. Name should start with a letter, consist of the " \
|
42
|
+
'letters A-Z, a-z, 0-9 or _ and be at least 3 characters long.'
|
43
|
+
end
|
41
44
|
|
42
45
|
custom_attributes[str_name] = value
|
43
46
|
end
|
@@ -54,7 +57,7 @@ module MediaTypes
|
|
54
57
|
inner = error.cause
|
55
58
|
return nil if inner.nil?
|
56
59
|
|
57
|
-
"https://docs.delftsolutions.nl/wiki/Error/#{ERB::Util
|
60
|
+
"https://docs.delftsolutions.nl/wiki/Error/#{ERB::Util.url_encode(inner.class.name)}"
|
58
61
|
end
|
59
62
|
|
60
63
|
def languages
|
@@ -16,7 +16,7 @@ module MediaTypes
|
|
16
16
|
return uri unless viewer.host == current_host
|
17
17
|
|
18
18
|
query_parts = viewer.query&.split('&') || []
|
19
|
-
query_parts = query_parts.
|
19
|
+
query_parts = query_parts.reject { |p| p.starts_with?('api_viewer=') }
|
20
20
|
query_parts.append("api_viewer=#{type}")
|
21
21
|
viewer.query = query_parts.join('&')
|
22
22
|
viewer.to_s
|
@@ -45,42 +45,45 @@ module MediaTypes
|
|
45
45
|
result = {
|
46
46
|
identifier: identifier,
|
47
47
|
href: viewerify(context.request.original_url, context.request.host, type: identifier),
|
48
|
-
selected: identifier == original_identifier
|
48
|
+
selected: identifier == original_identifier
|
49
49
|
}
|
50
50
|
result[:href] = '#output' if identifier == original_identifier
|
51
51
|
|
52
52
|
result
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
map { |l| CGI
|
58
|
-
map
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
55
|
+
escaped_output = original_output
|
56
|
+
&.split("\n")
|
57
|
+
&.map { |l| CGI.escapeHTML(l).gsub(/ (?= )/, ' ') }
|
58
|
+
&.map do |l|
|
59
|
+
l.gsub(/\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;{}]*[-A-Z0-9+@#\/%=}~_|](?![a-z]*;)/i) do |m|
|
60
|
+
converted = m
|
61
|
+
invalid = false
|
62
|
+
begin
|
63
|
+
converted = viewerify(m, context.request.host)
|
64
|
+
rescue URI::InvalidURIError
|
65
|
+
invalid = true
|
66
|
+
end
|
67
|
+
style = ''
|
68
|
+
style = ' style="color: red"' if invalid
|
69
|
+
"<a#{style} href=\"#{converted}\">#{m}</a>"
|
65
70
|
end
|
66
|
-
|
67
|
-
|
68
|
-
"<a#{style} href=\"#{converted}\">#{m}</a>"
|
69
|
-
end) }.
|
70
|
-
join("<br>\n")
|
71
|
-
|
71
|
+
end
|
72
|
+
&.join("<br>\n")
|
72
73
|
|
73
74
|
input = OpenStruct.new(
|
74
75
|
original_identifier: original_identifier,
|
75
76
|
escaped_output: escaped_output,
|
76
77
|
api_fied_links: api_fied_links,
|
77
78
|
media_types: media_types,
|
78
|
-
css: CommonCSS.css
|
79
|
+
css: CommonCSS.css
|
79
80
|
)
|
80
81
|
|
81
82
|
template = ERB.new <<-TEMPLATE
|
82
83
|
<html lang="en">
|
83
84
|
<head>
|
85
|
+
<meta content="width=device-width, initial-scale=1" name="viewport">
|
86
|
+
|
84
87
|
<title>API Viewer [<%= CGI::escapeHTML(original_identifier) %>]</title>
|
85
88
|
<style>
|
86
89
|
<%= css.split("\n").join("\n ") %>
|
@@ -15,28 +15,28 @@ module MediaTypes
|
|
15
15
|
self.logo_media_type = 'image/svg+xml'
|
16
16
|
self.logo_width = 8
|
17
17
|
self.logo_data = <<-HERE
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
18
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 114 93">
|
19
|
+
<title>Delft Solutions</title>
|
20
|
+
|
21
|
+
<filter id="dropshadow">
|
22
|
+
<feGaussianBlur in="SourceAlpha" stdDeviation="1"></feGaussianBlur> <!-- stdDeviation is how much to blur -->
|
23
|
+
<feOffset dx="2" dy="1" result="offsetblur"></feOffset> <!-- how much to offset -->
|
24
|
+
<feComponentTransfer>
|
25
|
+
<feFuncA type="linear" slope="0.5"></feFuncA> <!-- slope is the opacity of the shadow -->
|
26
|
+
</feComponentTransfer>
|
27
|
+
<feMerge>
|
28
|
+
<feMergeNode></feMergeNode> <!-- this contains the offset blurred image -->
|
29
|
+
<feMergeNode in="SourceGraphic"></feMergeNode> <!-- this contains the element that the filter is applied to -->
|
30
|
+
</feMerge>
|
31
|
+
</filter>
|
32
|
+
|
33
|
+
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
34
|
+
<g fill="#FFFFFF" fill-rule="nonzero">
|
35
|
+
|
36
|
+
<path d="M81.5784638,1.07718279e-13 C82.7664738,1.07718279e-13 83.8032488,0.734079641 84.4157016,1.75205281 L109.531129,43.5095713 C110.813908,45.6417099 110.657922,48.2974919 109.15835,50.2831454 L80.6973102,87.9923196 C80.0557678,88.7870619 79.0855103,89.3973447 78.0602378,89.3973447 L42.8594985,89.3973447 L14.6289023,43.5796094 L38.1043811,13.5281311 L47.8307983,13.5281311 L25.7347121,43.6175319 L48.0361926,79.9158441 L75.0253918,79.9158441 L101.326814,46.2820182 L73.5454136,1.07718279e-13 L81.5784638,1.07718279e-13 Z M68.8174965,0.000338312914 L96.4191607,45.9808751 L73.2382461,75.6684695 L61.4283598,75.6684695 L84.975762,45.385564 L63.4142078,9.46643441 L36.1380842,9.46643441 L9.60299852,43.3032035 L35.9112712,85.3931029 L38.1241857,89.3191214 L29.1498474,89.3973434 C27.9592604,89.4075947 26.8506993,88.7919375 26.2302294,87.7757572 L0.893096605,46.2796422 C-0.418595034,44.1314075 -0.274907213,41.3978442 1.25477457,39.3989643 L30.388821,1.32865425 L30.4563519,1.24328222 C31.0981823,0.458113729 32.0600455,0.000338312914 33.0779839,0.000338312914 L68.8174965,0.000338312914 Z" id="logo-mark-colour"></path>
|
37
|
+
</g>
|
38
|
+
</g>
|
39
|
+
</svg>
|
40
40
|
HERE
|
41
41
|
|
42
42
|
def self.logo_url
|
@@ -78,7 +78,7 @@ module MediaTypes
|
|
78
78
|
a:hover {
|
79
79
|
color: #5E7EFF;
|
80
80
|
}
|
81
|
-
|
81
|
+
|
82
82
|
#logo {
|
83
83
|
width: <%= logo_width %>em;
|
84
84
|
height: 6em;
|
@@ -160,7 +160,7 @@ module MediaTypes
|
|
160
160
|
TEMPLATE
|
161
161
|
template = ERB.new custom_css unless custom_css.nil?
|
162
162
|
|
163
|
-
template.result(binding
|
163
|
+
template.result(binding)
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
@@ -11,21 +11,24 @@ module MediaTypes
|
|
11
11
|
unvalidated 'text/html'
|
12
12
|
|
13
13
|
def self.escape_text(text)
|
14
|
-
text
|
15
|
-
|
16
|
-
map { |l| (l.gsub(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
text
|
15
|
+
.split("\n")
|
16
|
+
.map { |l| CGI.escapeHTML(l).gsub(/ (?= )/, ' ') }
|
17
|
+
.map do |l|
|
18
|
+
l.gsub(/\bhttps?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;{}]*[-A-Z0-9+@#\/%=}~_|](?![a-z]*;)/i) do |m|
|
19
|
+
converted = m
|
20
|
+
invalid = false
|
21
|
+
begin
|
22
|
+
converted = viewerify(m, context.request.host)
|
23
|
+
rescue URI::InvalidURIError
|
24
|
+
invalid = true
|
25
|
+
end
|
26
|
+
style = ''
|
27
|
+
style = ' style="color: red"' if invalid
|
28
|
+
"<a#{style} href=\"#{converted}\">#{m}</a>"
|
23
29
|
end
|
24
|
-
|
25
|
-
|
26
|
-
"<a#{style} href=\"#{converted}\">#{m}</a>"
|
27
|
-
end) }.
|
28
|
-
join("<br>\n")
|
30
|
+
end
|
31
|
+
.join("<br>\n")
|
29
32
|
end
|
30
33
|
|
31
34
|
output_raw do |obj, version, context|
|
@@ -46,6 +49,7 @@ module MediaTypes
|
|
46
49
|
template = ERB.new <<-TEMPLATE
|
47
50
|
<html lang="en">
|
48
51
|
<head>
|
52
|
+
<meta content="width=device-width, initial-scale=1" name="viewport">
|
49
53
|
<title>Invalid input detected</title>
|
50
54
|
<style>
|
51
55
|
<%= css.split("\n").join("\n ") %>
|
@@ -15,7 +15,9 @@ module MediaTypes
|
|
15
15
|
output do |problem, _, context|
|
16
16
|
raise 'No translations defined, add at least one title' unless problem.translations.keys.any?
|
17
17
|
|
18
|
-
accept_language_header = Utils::AcceptLanguageHeader.new(
|
18
|
+
accept_language_header = Utils::AcceptLanguageHeader.new(
|
19
|
+
context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
|
20
|
+
)
|
19
21
|
translation_entry = accept_language_header.map do |locale|
|
20
22
|
problem.translations.keys.find do |l|
|
21
23
|
l.start_with? locale.locale
|
@@ -40,7 +42,9 @@ module MediaTypes
|
|
40
42
|
output_alias 'application/problem+json'
|
41
43
|
|
42
44
|
output_raw view: :html do |problem, _, context|
|
43
|
-
accept_language_header = Utils::AcceptLanguageHeader.new(
|
45
|
+
accept_language_header = Utils::AcceptLanguageHeader.new(
|
46
|
+
context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
|
47
|
+
)
|
44
48
|
translation_entry = accept_language_header.map do |locale|
|
45
49
|
problem.translations.keys.find do |l|
|
46
50
|
l.starts_with? locale.locale
|
@@ -57,12 +61,13 @@ module MediaTypes
|
|
57
61
|
title: title,
|
58
62
|
detail: detail,
|
59
63
|
help_url: problem.type,
|
60
|
-
css: CommonCSS.css
|
64
|
+
css: CommonCSS.css
|
61
65
|
)
|
62
66
|
|
63
67
|
template = ERB.new <<-TEMPLATE
|
64
68
|
<html lang="en">
|
65
69
|
<head>
|
70
|
+
<meta content="width=device-width, initial-scale=1" name="viewport">
|
66
71
|
<title>Error - <%= CGI::escapeHTML(title) %></title>
|
67
72
|
<style>
|
68
73
|
<%= css.split("\n").join("\n ") %>
|
@@ -93,7 +98,6 @@ module MediaTypes
|
|
93
98
|
enable_wildcards
|
94
99
|
|
95
100
|
output_alias_optional 'text/html', view: :html
|
96
|
-
|
97
101
|
end
|
98
102
|
end
|
99
103
|
end
|