media_types-serialization 2.0.4 → 2.2.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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/.github/workflows/publish-trixie.yml +34 -0
- data/.vscode/settings.json +11 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +103 -90
- data/README.md +10 -0
- data/lib/media_types/serialization/fake_validator.rb +1 -1
- data/lib/media_types/serialization/serialization_dsl.rb +4 -0
- data/lib/media_types/serialization/serializers/api_viewer.rb +103 -73
- data/lib/media_types/serialization/serializers/endpoint_description_serializer.rb +21 -21
- data/lib/media_types/serialization/serializers/input_validation_error_serializer.rb +7 -5
- data/lib/media_types/serialization/serializers/problem_serializer.rb +1 -1
- data/lib/media_types/serialization/version.rb +1 -1
- data/media_types-serialization.gemspec +4 -4
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c56dd5b756ebbfe9526f1c08b3d207d23bac3eb3ca7733d21adaaac021fb90b9
|
4
|
+
data.tar.gz: 79afb8d97da4a28c2c1085a12df97d22462b7bad521df4d0114d8d6e19c27d64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0373faa865ffd99f08385c1a90af40e483e3dd9e4e443113f1d2c67942ddd41ec67e5d272607efe6025d088861182831e446997010a20c0d0df75b1b3d43375f
|
7
|
+
data.tar.gz: 829b344f7c90958f0d81dbb83aee66f7df988cd9f091ce199d99cb917e58069847900de0b6b60ad51a5aa0cc845bf439a9c75ee5c35bfc4dfa96c326401e5139
|
data/.github/workflows/ci.yml
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish debian trixie packages
|
2
|
+
|
3
|
+
on:
|
4
|
+
- workflow_dispatch
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish-trixie:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
container:
|
10
|
+
image: debian:trixie
|
11
|
+
steps:
|
12
|
+
- name: Install repo
|
13
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install wget && wget -O key.deb https://deb1.ws.maxmaton.nl/key.deb && DEBIAN_FRONTEND=noninteractive apt-get --yes install ./key.deb && echo "deb [signed-by=/usr/share/keyrings/maxmaton.gpg] http://deb.maxmaton.nl/debian trixie main non-free" > /etc/apt/sources.list.d/maxmaton.list
|
14
|
+
- name: Install dependencies
|
15
|
+
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --yes install git build-essential gem scrypt sshpass gem2deb ruby-actionpack ruby-activesupport ruby-media-types
|
16
|
+
- uses: actions/checkout@v3
|
17
|
+
name: Check out repository
|
18
|
+
- name: Build gem
|
19
|
+
run: |
|
20
|
+
git config --global --add safe.directory "$(pwd)"
|
21
|
+
sed -i -re "s/VERSION\s+=\s+'([0-9]+.[0-9]+.[0-9]+)'/VERSION = '\1.trixie'/g" lib/media_types/serialization/version.rb
|
22
|
+
gem build media_types-serialization.gemspec
|
23
|
+
- name: Build deb
|
24
|
+
run: DEBEMAIL=info@delftsolutions.nl gem2deb media_types-serialization-*.gem && ls -hal
|
25
|
+
- name: Publish
|
26
|
+
env:
|
27
|
+
PUBLISH_SIGNING_KEY: ${{ secrets.PUBLISH_SIGNING_KEY }}
|
28
|
+
SSHPASS: ${{ secrets.SSHPASS }}
|
29
|
+
run: |
|
30
|
+
echo "deb1.ws.maxmaton.nl ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgN3TiyKvRTj4xBSyQtYz0OuHZYv2i+x3NL+svh2k0SgPr0Xms4Vu+g3AXntXUQGRM0W9zbcZSHiBIWbliv3Y+20f7lKlj9uXUEMHDuiB7Fu7dXObfHswIvTX3XWiPdDeG1jYQbGM3tENX/wtEoixyL++33O69t2SFR5MkPk+/j+zlGLCFf0ypTAMb7bT5NjRNM3+v0LT2WVSZuawA7Fl8WBVTq7MSSuCZIxHIv1kEq6AWpOjWZHNVZrijs+uRTIPcrZ47wSt6tanjAnWT9sAzu8KqcvQsPw9IQwqV1nfQWz0wMit7ijn9B3MrkNHXP5PaNiZQCezsbrh9glhShz0z" > known_hosts
|
31
|
+
echo "deb1.ws.maxmaton.nl ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMr5uAraiRj0pQ9Q9dQO0xMosTzFUAe+VjtMclIUbdJ7r7XMUa3etxh3BfBlW4nq3ZdIFCsV2zwzTaYSmfh95Xs=" >> known_hosts
|
32
|
+
echo "deb1.ws.maxmaton.nl ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPhQl7Ik6h7hSQbdo9ZfF78WYFCzch8SAOXFBxxAZH06" >> known_hosts
|
33
|
+
echo "Uploading :" ruby-media-types-serialization_*.deb
|
34
|
+
scrypt enc --passphrase "env:PUBLISH_SIGNING_KEY" ruby-media-types-serialization_*.deb | sshpass -e ssh -o "UserKnownHostsFile=known_hosts" publish@deb1.ws.maxmaton.nl "echo 'uploading trixie' && sudo /opt/max/publish-deb ruby-media-types-serialization trixie main && echo 'trixie done'"
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.2.0
|
4
|
+
|
5
|
+
- ✨ Add `form_authenticity_token` support
|
6
|
+
- 🐛 Fix [output error failures on missing input](https://github.com/XPBytes/media_types-serialization/issues/267)
|
7
|
+
|
8
|
+
## 2.1.0
|
9
|
+
|
10
|
+
- ✨ Add `varies_on_header` serializer dsl function.
|
11
|
+
- 🐛 Fix [crash in input validation error serializer](https://github.com/XPBytes/media_types-serialization/issues/260)
|
12
|
+
- 🐛 Fix [endpoint description having media types multiple times](https://github.com/XPBytes/media_types-serialization/issues/184)
|
13
|
+
- 🐛 Fix problem serializer not Varying on Accept-Language
|
14
|
+
|
3
15
|
## 2.0.4
|
4
16
|
|
5
17
|
- ✨ Add more loose tests
|
data/Gemfile.lock
CHANGED
@@ -1,84 +1,87 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
media_types-serialization (2.0
|
5
|
-
actionpack (>= 6.
|
6
|
-
activesupport (>= 6.
|
4
|
+
media_types-serialization (2.1.0)
|
5
|
+
actionpack (>= 6.1.7.10)
|
6
|
+
activesupport (>= 6.1.7.10)
|
7
7
|
media_types (>= 2.2.3, < 3.0.0)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actioncable (6.1.7.
|
13
|
-
actionpack (= 6.1.7.
|
14
|
-
activesupport (= 6.1.7.
|
12
|
+
actioncable (6.1.7.10)
|
13
|
+
actionpack (= 6.1.7.10)
|
14
|
+
activesupport (= 6.1.7.10)
|
15
15
|
nio4r (~> 2.0)
|
16
16
|
websocket-driver (>= 0.6.1)
|
17
|
-
actionmailbox (6.1.7.
|
18
|
-
actionpack (= 6.1.7.
|
19
|
-
activejob (= 6.1.7.
|
20
|
-
activerecord (= 6.1.7.
|
21
|
-
activestorage (= 6.1.7.
|
22
|
-
activesupport (= 6.1.7.
|
17
|
+
actionmailbox (6.1.7.10)
|
18
|
+
actionpack (= 6.1.7.10)
|
19
|
+
activejob (= 6.1.7.10)
|
20
|
+
activerecord (= 6.1.7.10)
|
21
|
+
activestorage (= 6.1.7.10)
|
22
|
+
activesupport (= 6.1.7.10)
|
23
23
|
mail (>= 2.7.1)
|
24
|
-
actionmailer (6.1.7.
|
25
|
-
actionpack (= 6.1.7.
|
26
|
-
actionview (= 6.1.7.
|
27
|
-
activejob (= 6.1.7.
|
28
|
-
activesupport (= 6.1.7.
|
24
|
+
actionmailer (6.1.7.10)
|
25
|
+
actionpack (= 6.1.7.10)
|
26
|
+
actionview (= 6.1.7.10)
|
27
|
+
activejob (= 6.1.7.10)
|
28
|
+
activesupport (= 6.1.7.10)
|
29
29
|
mail (~> 2.5, >= 2.5.4)
|
30
30
|
rails-dom-testing (~> 2.0)
|
31
|
-
actionpack (6.1.7.
|
32
|
-
actionview (= 6.1.7.
|
33
|
-
activesupport (= 6.1.7.
|
31
|
+
actionpack (6.1.7.10)
|
32
|
+
actionview (= 6.1.7.10)
|
33
|
+
activesupport (= 6.1.7.10)
|
34
34
|
rack (~> 2.0, >= 2.0.9)
|
35
35
|
rack-test (>= 0.6.3)
|
36
36
|
rails-dom-testing (~> 2.0)
|
37
37
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
38
|
-
actiontext (6.1.7.
|
39
|
-
actionpack (= 6.1.7.
|
40
|
-
activerecord (= 6.1.7.
|
41
|
-
activestorage (= 6.1.7.
|
42
|
-
activesupport (= 6.1.7.
|
38
|
+
actiontext (6.1.7.10)
|
39
|
+
actionpack (= 6.1.7.10)
|
40
|
+
activerecord (= 6.1.7.10)
|
41
|
+
activestorage (= 6.1.7.10)
|
42
|
+
activesupport (= 6.1.7.10)
|
43
43
|
nokogiri (>= 1.8.5)
|
44
|
-
actionview (6.1.7.
|
45
|
-
activesupport (= 6.1.7.
|
44
|
+
actionview (6.1.7.10)
|
45
|
+
activesupport (= 6.1.7.10)
|
46
46
|
builder (~> 3.1)
|
47
47
|
erubi (~> 1.4)
|
48
48
|
rails-dom-testing (~> 2.0)
|
49
49
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
50
|
-
activejob (6.1.7.
|
51
|
-
activesupport (= 6.1.7.
|
50
|
+
activejob (6.1.7.10)
|
51
|
+
activesupport (= 6.1.7.10)
|
52
52
|
globalid (>= 0.3.6)
|
53
|
-
activemodel (6.1.7.
|
54
|
-
activesupport (= 6.1.7.
|
55
|
-
activerecord (6.1.7.
|
56
|
-
activemodel (= 6.1.7.
|
57
|
-
activesupport (= 6.1.7.
|
58
|
-
activestorage (6.1.7.
|
59
|
-
actionpack (= 6.1.7.
|
60
|
-
activejob (= 6.1.7.
|
61
|
-
activerecord (= 6.1.7.
|
62
|
-
activesupport (= 6.1.7.
|
53
|
+
activemodel (6.1.7.10)
|
54
|
+
activesupport (= 6.1.7.10)
|
55
|
+
activerecord (6.1.7.10)
|
56
|
+
activemodel (= 6.1.7.10)
|
57
|
+
activesupport (= 6.1.7.10)
|
58
|
+
activestorage (6.1.7.10)
|
59
|
+
actionpack (= 6.1.7.10)
|
60
|
+
activejob (= 6.1.7.10)
|
61
|
+
activerecord (= 6.1.7.10)
|
62
|
+
activesupport (= 6.1.7.10)
|
63
63
|
marcel (~> 1.0)
|
64
64
|
mini_mime (>= 1.1.0)
|
65
|
-
activesupport (6.1.7.
|
65
|
+
activesupport (6.1.7.10)
|
66
66
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
67
67
|
i18n (>= 1.6, < 2)
|
68
68
|
minitest (>= 5.1)
|
69
69
|
tzinfo (~> 2.0)
|
70
70
|
zeitwerk (~> 2.3)
|
71
71
|
awesome_print (1.9.2)
|
72
|
-
|
73
|
-
|
72
|
+
base64 (0.3.0)
|
73
|
+
bigdecimal (3.2.2)
|
74
|
+
builder (3.3.0)
|
75
|
+
concurrent-ruby (1.3.5)
|
74
76
|
crass (1.0.6)
|
75
|
-
date (3.
|
76
|
-
erubi (1.
|
77
|
-
globalid (1.1
|
78
|
-
activesupport (>=
|
79
|
-
i18n (1.14.
|
77
|
+
date (3.4.1)
|
78
|
+
erubi (1.13.1)
|
79
|
+
globalid (1.2.1)
|
80
|
+
activesupport (>= 6.1)
|
81
|
+
i18n (1.14.7)
|
80
82
|
concurrent-ruby (~> 1.0)
|
81
|
-
|
83
|
+
logger (1.7.0)
|
84
|
+
loofah (2.24.1)
|
82
85
|
crass (~> 1.0.2)
|
83
86
|
nokogiri (>= 1.12.0)
|
84
87
|
mail (2.8.1)
|
@@ -86,84 +89,94 @@ GEM
|
|
86
89
|
net-imap
|
87
90
|
net-pop
|
88
91
|
net-smtp
|
89
|
-
marcel (1.0.
|
92
|
+
marcel (1.0.4)
|
90
93
|
media_types (2.3.2)
|
91
|
-
method_source (1.
|
94
|
+
method_source (1.1.0)
|
92
95
|
mini_mime (1.1.5)
|
93
|
-
|
94
|
-
|
96
|
+
mini_portile2 (2.8.9)
|
97
|
+
minitest (5.25.5)
|
98
|
+
net-imap (0.5.9)
|
95
99
|
date
|
96
100
|
net-protocol
|
97
101
|
net-pop (0.1.2)
|
98
102
|
net-protocol
|
99
|
-
net-protocol (0.2.
|
103
|
+
net-protocol (0.2.2)
|
100
104
|
timeout
|
101
|
-
net-smtp (0.
|
105
|
+
net-smtp (0.5.1)
|
102
106
|
net-protocol
|
103
|
-
nio4r (2.
|
104
|
-
nokogiri (1.
|
107
|
+
nio4r (2.7.4)
|
108
|
+
nokogiri (1.18.9)
|
109
|
+
mini_portile2 (~> 2.8.2)
|
105
110
|
racc (~> 1.4)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
111
|
+
nokogiri (1.18.9-x64-mingw-ucrt)
|
112
|
+
racc (~> 1.4)
|
113
|
+
oj (3.16.11)
|
114
|
+
bigdecimal (>= 3.0)
|
115
|
+
ostruct (>= 0.2)
|
116
|
+
ostruct (0.6.3)
|
117
|
+
racc (1.8.1)
|
118
|
+
rack (2.2.17)
|
119
|
+
rack-test (2.2.0)
|
110
120
|
rack (>= 1.3)
|
111
|
-
rails (6.1.7.
|
112
|
-
actioncable (= 6.1.7.
|
113
|
-
actionmailbox (= 6.1.7.
|
114
|
-
actionmailer (= 6.1.7.
|
115
|
-
actionpack (= 6.1.7.
|
116
|
-
actiontext (= 6.1.7.
|
117
|
-
actionview (= 6.1.7.
|
118
|
-
activejob (= 6.1.7.
|
119
|
-
activemodel (= 6.1.7.
|
120
|
-
activerecord (= 6.1.7.
|
121
|
-
activestorage (= 6.1.7.
|
122
|
-
activesupport (= 6.1.7.
|
121
|
+
rails (6.1.7.10)
|
122
|
+
actioncable (= 6.1.7.10)
|
123
|
+
actionmailbox (= 6.1.7.10)
|
124
|
+
actionmailer (= 6.1.7.10)
|
125
|
+
actionpack (= 6.1.7.10)
|
126
|
+
actiontext (= 6.1.7.10)
|
127
|
+
actionview (= 6.1.7.10)
|
128
|
+
activejob (= 6.1.7.10)
|
129
|
+
activemodel (= 6.1.7.10)
|
130
|
+
activerecord (= 6.1.7.10)
|
131
|
+
activestorage (= 6.1.7.10)
|
132
|
+
activesupport (= 6.1.7.10)
|
123
133
|
bundler (>= 1.15.0)
|
124
|
-
railties (= 6.1.7.
|
134
|
+
railties (= 6.1.7.10)
|
125
135
|
sprockets-rails (>= 2.0.0)
|
126
|
-
rails-dom-testing (2.
|
136
|
+
rails-dom-testing (2.3.0)
|
127
137
|
activesupport (>= 5.0.0)
|
128
138
|
minitest
|
129
139
|
nokogiri (>= 1.6)
|
130
|
-
rails-html-sanitizer (1.6.
|
140
|
+
rails-html-sanitizer (1.6.2)
|
131
141
|
loofah (~> 2.21)
|
132
|
-
nokogiri (
|
133
|
-
railties (6.1.7.
|
134
|
-
actionpack (= 6.1.7.
|
135
|
-
activesupport (= 6.1.7.
|
142
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
143
|
+
railties (6.1.7.10)
|
144
|
+
actionpack (= 6.1.7.10)
|
145
|
+
activesupport (= 6.1.7.10)
|
136
146
|
method_source
|
137
147
|
rake (>= 12.2)
|
138
148
|
thor (~> 1.0)
|
139
149
|
rake (13.0.6)
|
140
|
-
sprockets (4.2.
|
150
|
+
sprockets (4.2.2)
|
141
151
|
concurrent-ruby (~> 1.0)
|
152
|
+
logger
|
142
153
|
rack (>= 2.2.4, < 4)
|
143
|
-
sprockets-rails (3.
|
144
|
-
actionpack (>=
|
145
|
-
activesupport (>=
|
154
|
+
sprockets-rails (3.5.2)
|
155
|
+
actionpack (>= 6.1)
|
156
|
+
activesupport (>= 6.1)
|
146
157
|
sprockets (>= 3.0.0)
|
147
|
-
thor (1.
|
148
|
-
timeout (0.4.
|
158
|
+
thor (1.4.0)
|
159
|
+
timeout (0.4.3)
|
149
160
|
tzinfo (2.0.6)
|
150
161
|
concurrent-ruby (~> 1.0)
|
151
|
-
websocket-driver (0.
|
162
|
+
websocket-driver (0.8.0)
|
163
|
+
base64
|
152
164
|
websocket-extensions (>= 0.1.0)
|
153
165
|
websocket-extensions (0.1.5)
|
154
|
-
zeitwerk (2.6.
|
166
|
+
zeitwerk (2.6.18)
|
155
167
|
|
156
168
|
PLATFORMS
|
169
|
+
x64-mingw-ucrt
|
157
170
|
x64-mingw32
|
158
171
|
|
159
172
|
DEPENDENCIES
|
160
173
|
awesome_print
|
161
174
|
bundler
|
162
175
|
media_types-serialization!
|
163
|
-
minitest (~> 5.
|
176
|
+
minitest (~> 5.17)
|
164
177
|
oj
|
165
|
-
rails (~> 6.
|
178
|
+
rails (~> 6.1.7.10)
|
166
179
|
rake (~> 13.0)
|
167
180
|
|
168
181
|
BUNDLED WITH
|
169
|
-
2.
|
182
|
+
2.3.15
|
data/README.md
CHANGED
@@ -897,6 +897,16 @@ This redirects the user to the specified url when this serializer is rendered. T
|
|
897
897
|
|
898
898
|
Replaces the render at the end of `render_media` and substitutes it with the contents of the block.
|
899
899
|
|
900
|
+
#### `varies_on_header(header)`
|
901
|
+
|
902
|
+
Indicates to clients that they can receive a different response if the indicated header has a different value. This is done using the [Vary header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Vary). When your responses are internationalized you can use the following example:
|
903
|
+
|
904
|
+
```ruby
|
905
|
+
varies_on_header 'Accept-Language'
|
906
|
+
```
|
907
|
+
|
908
|
+
The Vary header is set at two moments during execution. The first moment the header is modified is during the `freeze_io!` handler. The second moment is when `render_media` is called. If you want to modify the Vary header that is returned when the content negotiation fails you need to make sure to run your callback before the `freeze_io!` callback has been run.
|
909
|
+
|
900
910
|
### Controller definition
|
901
911
|
|
902
912
|
These functions are available during the controller definition if you add `include MediaTypes::Serialization`.
|
@@ -114,6 +114,10 @@ module MediaTypes
|
|
114
114
|
context.serialization_dsl_result
|
115
115
|
end
|
116
116
|
|
117
|
+
def varies_on_header(header)
|
118
|
+
@serialization_vary.push(header) unless @serialization_vary.include? header
|
119
|
+
end
|
120
|
+
|
117
121
|
def redirect_to(url, context, **options)
|
118
122
|
suppress_render do |result|
|
119
123
|
context.redirect_to(
|
@@ -33,7 +33,7 @@ module MediaTypes
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.allowed_replies(context, actions)
|
36
|
+
def self.allowed_replies(context, actions = {})
|
37
37
|
request_path = context.request.original_fullpath.split('?')[0]
|
38
38
|
|
39
39
|
path_prefix = ENV.fetch('RAILS_RELATIVE_URL_ROOT') { '' }
|
@@ -160,10 +160,11 @@ module MediaTypes
|
|
160
160
|
etag: obj[:etag],
|
161
161
|
allowed_replies: allowed_replies(context, obj[:actions]),
|
162
162
|
escape_javascript: method(:escape_javascript),
|
163
|
-
unviewered_uri: unviewered_uri
|
163
|
+
unviewered_uri: unviewered_uri,
|
164
|
+
token: context.try(:form_authenticity_token)
|
164
165
|
)
|
165
166
|
|
166
|
-
template = ERB.new <<-
|
167
|
+
template = ERB.new <<-HTML
|
167
168
|
<!DOCTYPE html>
|
168
169
|
<html lang="en">
|
169
170
|
<head>
|
@@ -228,98 +229,127 @@ module MediaTypes
|
|
228
229
|
<label class="form-row"><div class="cell label">Receive:</div> <select class="cell" name="response-content-type"></select></label>
|
229
230
|
</div>
|
230
231
|
<textarea name="request-content"></textarea>
|
231
|
-
|
232
|
+
<% if token %>
|
233
|
+
<input type="hidden" name="authenticity_token" value="<%= token %>">
|
234
|
+
<% end %>
|
235
|
+
<input type="submit" name="submit" value="Reply"><span id="reply-status-code" hidden> - sending...</span>
|
232
236
|
<hr>
|
233
237
|
<code id="reply-response" hidden>
|
234
238
|
</code>
|
235
239
|
</form>
|
236
240
|
<script>
|
237
241
|
{
|
238
|
-
|
239
|
-
form.removeAttribute('hidden')
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
contentElem.
|
257
|
-
|
242
|
+
const form = document.getElementById("reply-form");
|
243
|
+
form.removeAttribute('hidden');
|
244
|
+
|
245
|
+
const actionData = JSON.parse("<%= escape_javascript.call(allowed_replies.to_json) %>");
|
246
|
+
|
247
|
+
const methodElem = form.elements["method"];
|
248
|
+
const requestTypeElem = form.elements["request-content-type"];
|
249
|
+
const responseTypeElem = form.elements["response-content-type"];
|
250
|
+
const contentElem = form.elements["request-content"];
|
251
|
+
const submitElem = form.elements["submit"];
|
252
|
+
const tokenElem = form.elements["authenticity_token"];
|
253
|
+
const replyResponseElem = document.getElementById("reply-response");
|
254
|
+
const replyStatusCodeElem = document.getElementById("reply-status-code");
|
255
|
+
|
256
|
+
const selectRequestType = function selectRequestType() {
|
257
|
+
const selected = requestTypeElem.value;
|
258
|
+
|
259
|
+
if (selected == "") {
|
260
|
+
contentElem.setAttribute("hidden", "");
|
261
|
+
} else {
|
262
|
+
contentElem.removeAttribute("hidden");
|
263
|
+
}
|
264
|
+
|
258
265
|
if (methodElem.value == "PUT" && contentElem.value.trim() == "") {
|
259
|
-
|
266
|
+
const currentRequestType = document.querySelector("#representations .active").textContent.trim()
|
267
|
+
|
260
268
|
if (currentRequestType == requestTypeElem.value) {
|
261
|
-
|
269
|
+
const outputElem = document.getElementById("output")
|
262
270
|
contentElem.value = outputElem.
|
263
271
|
textContent.
|
264
272
|
trim().
|
265
|
-
replaceAll(String.fromCharCode(160), " ")
|
273
|
+
replaceAll(String.fromCharCode(160), " ");
|
266
274
|
}
|
267
275
|
}
|
268
276
|
}
|
269
277
|
|
270
|
-
|
271
|
-
|
278
|
+
const selectMethod = function selectMethod() {
|
279
|
+
const selected = methodElem.value
|
272
280
|
submitElem.setAttribute("value", selected)
|
273
281
|
|
274
|
-
|
282
|
+
const mediatypes = actionData[selected]
|
275
283
|
|
276
|
-
while(requestTypeElem.firstChild)
|
284
|
+
while(requestTypeElem.firstChild) {
|
277
285
|
requestTypeElem.removeChild(requestTypeElem.lastChild)
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
option
|
282
|
-
|
286
|
+
}
|
287
|
+
|
288
|
+
mediatypes["input"].forEach((mediatype) => {
|
289
|
+
const option = document.createElement("option");
|
290
|
+
option.setAttribute("value", mediatype);
|
291
|
+
option.textContent = mediatype;
|
292
|
+
|
293
|
+
requestTypeElem.appendChild(option);
|
283
294
|
})
|
284
|
-
|
285
|
-
noneOption.
|
286
|
-
noneOption.
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
295
|
+
|
296
|
+
const noneOption = document.createElement("option");
|
297
|
+
noneOption.setAttribute("value", "");
|
298
|
+
noneOption.textContent = "None";
|
299
|
+
requestTypeElem.appendChild(noneOption);
|
300
|
+
|
301
|
+
while(responseTypeElem.firstChild) {
|
302
|
+
responseTypeElem.removeChild(responseTypeElem.lastChild);
|
303
|
+
}
|
304
|
+
|
305
|
+
mediatypes["output"].forEach((mediatype) => {
|
306
|
+
const option = document.createElement("option");
|
307
|
+
option.setAttribute("value", mediatype);
|
308
|
+
option.textContent = mediatype;
|
309
|
+
|
310
|
+
responseTypeElem.appendChild(option);
|
296
311
|
})
|
297
|
-
let anyOption = document.createElement("option")
|
298
|
-
anyOption.setAttribute("value", "")
|
299
|
-
anyOption.textContent = "Any"
|
300
|
-
responseTypeElem.appendChild(anyOption)
|
301
312
|
|
302
|
-
|
313
|
+
const anyOption = document.createElement("option");
|
314
|
+
anyOption.setAttribute("value", "");
|
315
|
+
anyOption.textContent = "Any";
|
316
|
+
responseTypeElem.appendChild(anyOption);
|
317
|
+
|
318
|
+
selectRequestType();
|
303
319
|
}
|
304
320
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
321
|
+
const onSubmit = async function onSubmit(event) {
|
322
|
+
event.preventDefault();
|
323
|
+
|
324
|
+
submitElem.setAttribute("disabled", "");
|
325
|
+
|
326
|
+
const method = methodElem.value
|
327
|
+
const requestContentType = requestTypeElem.value
|
328
|
+
const requestContent = contentElem.value
|
329
|
+
const token = tokenElem.value
|
330
|
+
|
331
|
+
let responseAccept = responseTypeElem.value + ", application/problem+json; q=0.2, */*; q=0.1"
|
332
|
+
if (responseTypeElem.value == "") {
|
312
333
|
responseAccept = "application/problem+json, */*; q=0.1"
|
334
|
+
}
|
313
335
|
|
314
|
-
|
336
|
+
const headers = {
|
315
337
|
Accept: responseAccept,
|
338
|
+
"X-Requested-With": "XMLHttpRequest"
|
316
339
|
}
|
340
|
+
|
341
|
+
|
342
|
+
if (method !== "GET" && token) {
|
343
|
+
headers["X-CSRF-Token"] = token
|
344
|
+
}
|
345
|
+
|
317
346
|
if (method == "PUT") {
|
318
|
-
|
347
|
+
const etag = "<%= escape_javascript.call(etag) %>"
|
319
348
|
if (etag != "") {
|
320
349
|
headers['If-Match'] = etag
|
321
350
|
}
|
322
351
|
}
|
352
|
+
|
323
353
|
let body = undefined
|
324
354
|
if (requestContentType != "") {
|
325
355
|
headers["Content-Type"] = requestContentType
|
@@ -331,32 +361,32 @@ module MediaTypes
|
|
331
361
|
replyStatusCodeElem.removeAttribute("hidden")
|
332
362
|
|
333
363
|
try {
|
334
|
-
|
364
|
+
const response = await fetch("<%= escape_javascript.call(unviewered_uri.to_s) %>", {
|
335
365
|
method: method,
|
336
366
|
mode: "same-origin",
|
337
367
|
credentials: "same-origin",
|
338
368
|
redirect: "follow",
|
339
369
|
headers: headers,
|
340
370
|
body: body
|
341
|
-
})
|
371
|
+
});
|
342
372
|
|
343
|
-
replyStatusCodeElem.textContent = " - Status " + response.status + " " + response.statusText
|
344
|
-
replyResponseElem.removeAttribute("hidden")
|
345
|
-
replyResponseElem.textContent = await response.text()
|
373
|
+
replyStatusCodeElem.textContent = " - Status " + response.status + " " + response.statusText;
|
374
|
+
replyResponseElem.removeAttribute("hidden");
|
375
|
+
replyResponseElem.textContent = await response.text();
|
346
376
|
replyResponseElem.innerHTML = replyResponseElem.
|
347
377
|
innerHTML.
|
348
378
|
replaceAll("\\n", "<br>\\n").
|
349
|
-
replaceAll(" ", " ")
|
379
|
+
replaceAll(" ", " ");
|
350
380
|
} catch (error) {
|
351
381
|
replyStatusCodeElem.textContent = " - Failed: " + error.message
|
352
382
|
} finally {
|
353
|
-
submitElem.removeAttribute("disabled")
|
383
|
+
submitElem.removeAttribute("disabled");
|
354
384
|
}
|
355
385
|
}
|
356
386
|
|
357
|
-
requestTypeElem.addEventListener("change", (
|
358
|
-
methodElem.addEventListener("change", (
|
359
|
-
|
387
|
+
requestTypeElem.addEventListener("change", () => selectRequestType());
|
388
|
+
methodElem.addEventListener("change", () => selectMethod());
|
389
|
+
form.addEventListener("submit", (e) => onSubmit(e));
|
360
390
|
|
361
391
|
addEventListener("DOMContentLoaded", (event) => selectMethod());
|
362
392
|
}
|
@@ -374,7 +404,7 @@ module MediaTypes
|
|
374
404
|
<!-- API viewer made with ❤ by: https://delftsolutions.com -->
|
375
405
|
</body>
|
376
406
|
</html>
|
377
|
-
|
407
|
+
HTML
|
378
408
|
template.result(input.instance_eval { binding })
|
379
409
|
end
|
380
410
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
require 'media_types/serialization/base'
|
@@ -7,41 +6,43 @@ module MediaTypes
|
|
7
6
|
module Serialization
|
8
7
|
module Serializers
|
9
8
|
class EndpointDescriptionSerializer < MediaTypes::Serialization::Base
|
10
|
-
|
11
9
|
unvalidated 'application/vnd.delftsolutions.endpoint_description'
|
12
10
|
|
13
11
|
disable_wildcards
|
14
12
|
|
15
13
|
def self.to_input_identifiers(serializers)
|
16
|
-
serializers
|
17
|
-
|
18
|
-
|
14
|
+
serializers
|
15
|
+
.flat_map do |s|
|
16
|
+
s[:serializer].inputs_for(views: [s[:view]]).registrations.keys
|
17
|
+
end
|
18
|
+
.uniq
|
19
19
|
end
|
20
|
+
|
20
21
|
def self.to_output_identifiers(serializers)
|
21
|
-
serializers
|
22
|
-
|
23
|
-
|
22
|
+
serializers
|
23
|
+
.flat_map do |s|
|
24
|
+
s[:serializer].outputs_for(views: [s[:view]]).registrations.keys
|
25
|
+
end
|
26
|
+
.uniq
|
24
27
|
end
|
25
28
|
|
26
|
-
output version: 1 do |input,
|
29
|
+
output version: 1 do |input, _version, context|
|
27
30
|
request_path = context.request.original_fullpath.split('?')[0]
|
28
31
|
|
29
|
-
path_prefix = ENV.fetch('RAILS_RELATIVE_URL_ROOT'
|
32
|
+
path_prefix = ENV.fetch('RAILS_RELATIVE_URL_ROOT', '')
|
30
33
|
request_path = request_path.sub(path_prefix, '')
|
31
34
|
|
32
35
|
my_controller = Rails.application.routes.recognize_path request_path
|
33
36
|
|
34
37
|
methods_available = {}
|
35
|
-
methods = [
|
38
|
+
methods = %w[GET POST PUT PATCH DELETE]
|
36
39
|
methods.each do |m|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
methods_available[m] = found_controller[:action]
|
41
|
-
end
|
42
|
-
rescue ActionController::RoutingError
|
43
|
-
# not available
|
40
|
+
found_controller = Rails.application.routes.recognize_path request_path, method: m
|
41
|
+
if found_controller[:controller] == my_controller[:controller]
|
42
|
+
methods_available[m] = found_controller[:action]
|
44
43
|
end
|
44
|
+
rescue ActionController::RoutingError
|
45
|
+
# not available
|
45
46
|
end
|
46
47
|
|
47
48
|
input_definitions = input[:actions][:input] || {}
|
@@ -55,8 +56,8 @@ module MediaTypes
|
|
55
56
|
|
56
57
|
viewer_uri = URI.parse(context.request.original_url)
|
57
58
|
query_parts = viewer_uri.query&.split('&') || []
|
58
|
-
query_parts = query_parts.
|
59
|
-
viewer_uri.query = (query_parts + [
|
59
|
+
query_parts = query_parts.reject { |q| q.start_with? 'api_viewer=' }
|
60
|
+
viewer_uri.query = (query_parts + ['api_viewer=last']).join('&')
|
60
61
|
|
61
62
|
methods_available.each do |method, action|
|
62
63
|
has_viewer = viewer_definitions[action] || global_viewer
|
@@ -73,7 +74,6 @@ module MediaTypes
|
|
73
74
|
|
74
75
|
result
|
75
76
|
end
|
76
|
-
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -10,8 +10,8 @@ module MediaTypes
|
|
10
10
|
class InputValidationErrorSerializer < MediaTypes::Serialization::Base
|
11
11
|
unvalidated 'text/html'
|
12
12
|
|
13
|
-
def self.escape_text(text)
|
14
|
-
text
|
13
|
+
def self.escape_text(text, context)
|
14
|
+
result = text
|
15
15
|
.split("\n")
|
16
16
|
.map { |l| CGI.escapeHTML(l).gsub(/ (?= )/, ' ') }
|
17
17
|
.map do |l|
|
@@ -19,7 +19,7 @@ module MediaTypes
|
|
19
19
|
converted = m
|
20
20
|
invalid = false
|
21
21
|
begin
|
22
|
-
converted = viewerify(m, context.request.host)
|
22
|
+
converted = ApiViewer.viewerify(m, context.request.host)
|
23
23
|
rescue URI::InvalidURIError
|
24
24
|
invalid = true
|
25
25
|
end
|
@@ -29,6 +29,8 @@ module MediaTypes
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
.join("<br>\n")
|
32
|
+
result.html_safe
|
33
|
+
result
|
32
34
|
end
|
33
35
|
|
34
36
|
output_raw do |obj, version, context|
|
@@ -36,8 +38,8 @@ module MediaTypes
|
|
36
38
|
original_input = obj[:input]
|
37
39
|
error = obj[:error]
|
38
40
|
|
39
|
-
escaped_error = escape_text(error.message)
|
40
|
-
escaped_input = escape_text(original_input)
|
41
|
+
escaped_error = escape_text(error.message, context)
|
42
|
+
escaped_input = escape_text(original_input, context)
|
41
43
|
|
42
44
|
input = OpenStruct.new(
|
43
45
|
original_identifier: input_identifier,
|
@@ -8,13 +8,13 @@ module MediaTypes
|
|
8
8
|
module Serialization
|
9
9
|
module Serializers
|
10
10
|
class ProblemSerializer < MediaTypes::Serialization::Base
|
11
|
-
|
12
11
|
unvalidated 'application/vnd.delftsolutions.problem'
|
13
12
|
disable_wildcards
|
14
13
|
|
15
14
|
output do |problem, _, context|
|
16
15
|
raise 'No translations defined, add at least one title' unless problem.translations.keys.any?
|
17
16
|
|
17
|
+
varies_on_header 'Accept-Language'
|
18
18
|
accept_language_header = Utils::AcceptLanguageHeader.new(
|
19
19
|
context.request.get_header(HEADER_ACCEPT_LANGUAGE) || ''
|
20
20
|
)
|
@@ -35,14 +35,14 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
36
36
|
spec.require_paths = ['lib']
|
37
37
|
|
38
|
-
spec.add_dependency 'actionpack', '>= 6.
|
39
|
-
spec.add_dependency 'activesupport', '>= 6.
|
38
|
+
spec.add_dependency 'actionpack', '>= 6.1.7.10'
|
39
|
+
spec.add_dependency 'activesupport', '>= 6.1.7.10'
|
40
40
|
spec.add_dependency 'media_types', '>= 2.2.3', '< 3.0.0'
|
41
41
|
|
42
42
|
spec.add_development_dependency 'awesome_print'
|
43
43
|
spec.add_development_dependency 'bundler'
|
44
|
-
spec.add_development_dependency 'rails', '~> 6.
|
44
|
+
spec.add_development_dependency 'rails', '~> 6.1.7.10'
|
45
45
|
spec.add_development_dependency 'rake', '~> 13.0'
|
46
|
-
spec.add_development_dependency 'minitest', '~> 5.
|
46
|
+
spec.add_development_dependency 'minitest', '~> 5.17'
|
47
47
|
spec.add_development_dependency 'oj'
|
48
48
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: media_types-serialization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derk-Jan Karrenbeld
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -17,28 +17,28 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 6.
|
20
|
+
version: 6.1.7.10
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 6.
|
27
|
+
version: 6.1.7.10
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: activesupport
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 6.
|
34
|
+
version: 6.1.7.10
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 6.
|
41
|
+
version: 6.1.7.10
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: media_types
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,14 +93,14 @@ dependencies:
|
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 6.1.7.10
|
97
97
|
type: :development
|
98
98
|
prerelease: false
|
99
99
|
version_requirements: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 6.1.7.10
|
104
104
|
- !ruby/object:Gem::Dependency
|
105
105
|
name: rake
|
106
106
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,14 +121,14 @@ dependencies:
|
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '5.
|
124
|
+
version: '5.17'
|
125
125
|
type: :development
|
126
126
|
prerelease: false
|
127
127
|
version_requirements: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '5.
|
131
|
+
version: '5.17'
|
132
132
|
- !ruby/object:Gem::Dependency
|
133
133
|
name: oj
|
134
134
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- ".github/workflows/ci.yml"
|
155
155
|
- ".github/workflows/publish-bookworm.yml"
|
156
156
|
- ".github/workflows/publish-sid.yml"
|
157
|
+
- ".github/workflows/publish-trixie.yml"
|
157
158
|
- ".gitignore"
|
158
159
|
- ".idea/.rakeTasks"
|
159
160
|
- ".idea/dictionaries/Derk_Jan.xml"
|
@@ -165,6 +166,7 @@ files:
|
|
165
166
|
- ".idea/runConfigurations/test.xml"
|
166
167
|
- ".idea/vcs.xml"
|
167
168
|
- ".prettierrc"
|
169
|
+
- ".vscode/settings.json"
|
168
170
|
- CHANGELOG.md
|
169
171
|
- CODE_OF_CONDUCT.md
|
170
172
|
- Gemfile
|
@@ -215,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
217
|
- !ruby/object:Gem::Version
|
216
218
|
version: '0'
|
217
219
|
requirements: []
|
218
|
-
rubygems_version: 3.
|
220
|
+
rubygems_version: 3.5.4
|
219
221
|
signing_key:
|
220
222
|
specification_version: 4
|
221
223
|
summary: Add media types supported serialization using your favourite serializer
|