media_types-serialization 1.4.0 → 2.0.4
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/publish-bookworm.yml +34 -0
- data/.github/workflows/publish-sid.yml +34 -0
- data/.gitignore +9 -1
- data/CHANGELOG.md +18 -0
- data/Gemfile.lock +169 -167
- data/README.md +4 -4
- data/lib/media_types/serialization/base.rb +71 -18
- data/lib/media_types/serialization/serialization_registration.rb +2 -2
- data/lib/media_types/serialization/serializers/api_viewer.rb +248 -1
- data/lib/media_types/serialization/serializers/common_css.rb +78 -34
- data/lib/media_types/serialization/version.rb +1 -1
- data/lib/media_types/serialization.rb +24 -10
- data/media_types-serialization.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 693624dcfef405aa51599edfecb2eb6d355d4e33b2ed862cae84da2ba38d1184
|
4
|
+
data.tar.gz: c6ef94f5cf139da3c4699fd15f4322b5417ca2840b62038b0c96580d6b3afed4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42cf5ba3382bb5863312d39c15cb5fb2565ef27ace28a06b6dfc565d766963649560501b1744e602e88d4c4d5d845c3b7c77a3d4640b2ddb5f17f7684da0f9de
|
7
|
+
data.tar.gz: 165bce5942688047c65b6d01c4c0657e8d311ad788456be0f6f84fd2536152a486d3e53a45f266cf8b357e4bc993d3832dcd52d61d48701c1a3de348736d7c9d
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish debian bookworm packages
|
2
|
+
|
3
|
+
on:
|
4
|
+
- workflow_dispatch
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish-bookworm:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
container:
|
10
|
+
image: debian:bookworm
|
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 bookworm 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.bookworm'/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 bookworm' && sudo /opt/max/publish-deb ruby-media-types-serialization bookworm main && echo 'bookworm done'"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish debian sid packages
|
2
|
+
|
3
|
+
on:
|
4
|
+
- workflow_dispatch
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
publish-sid:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
container:
|
10
|
+
image: debian:sid
|
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 sid 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.sid'/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 sid' && sudo /opt/max/publish-deb ruby-media-types-serialization sid main && echo 'sid done'"
|
data/.gitignore
CHANGED
@@ -11,4 +11,12 @@
|
|
11
11
|
.idea/usage.statistics.xml
|
12
12
|
.idea/tasks.xml
|
13
13
|
|
14
|
-
/media_types-serialization
|
14
|
+
/media_types-serialization-*.gem
|
15
|
+
/ruby-media-types-serialization-*
|
16
|
+
/media-types-serialization-*.tar.gz
|
17
|
+
/ruby-media-types-serialization_*.deb
|
18
|
+
/ruby-media-types-serialization_*.buildinfo
|
19
|
+
/ruby-media-types-serialization_*.changes
|
20
|
+
/ruby-media-types-serialization_*.debian.tar.xz
|
21
|
+
/ruby-media-types-serialization_*.dsc
|
22
|
+
/ruby-media-types-serialization_*.orig.tar.gz
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2.0.4
|
4
|
+
|
5
|
+
- ✨ Add more loose tests
|
6
|
+
- 🐛 Fix `locals` passing for HTML serialization
|
7
|
+
- 🐛 Fix for status passing in rack-like environments
|
8
|
+
|
9
|
+
## 2.0.3
|
10
|
+
|
11
|
+
- 🐛 Fix debian packages not containing files
|
12
|
+
|
13
|
+
## 2.0.0
|
14
|
+
|
15
|
+
- ✨ Add support for loose input validation
|
16
|
+
- ✨ Add inline api call functionality to api_viewer
|
17
|
+
- ✨ `allow_html_output` will now get the object in the `media` variable and if it is a hash, elements will be assigned as locals
|
18
|
+
- 🐛 Fix wildcards not showing up for non-nil views
|
19
|
+
- 🐛 Sending invalid content returned a 422 status code, changed to 400
|
20
|
+
|
3
21
|
## 1.4.0
|
4
22
|
|
5
23
|
- ✨ Add support for redirecting in serializers
|
data/Gemfile.lock
CHANGED
@@ -1,167 +1,169 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
media_types-serialization (
|
5
|
-
actionpack (>= 6.0.0)
|
6
|
-
activesupport (>= 6.0.0)
|
7
|
-
media_types (>= 2.2.
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: https://rubygems.org/
|
11
|
-
specs:
|
12
|
-
actioncable (6.1.7.
|
13
|
-
actionpack (= 6.1.7.
|
14
|
-
activesupport (= 6.1.7.
|
15
|
-
nio4r (~> 2.0)
|
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.
|
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.
|
29
|
-
mail (~> 2.5, >= 2.5.4)
|
30
|
-
rails-dom-testing (~> 2.0)
|
31
|
-
actionpack (6.1.7.
|
32
|
-
actionview (= 6.1.7.
|
33
|
-
activesupport (= 6.1.7.
|
34
|
-
rack (~> 2.0, >= 2.0.9)
|
35
|
-
rack-test (>= 0.6.3)
|
36
|
-
rails-dom-testing (~> 2.0)
|
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.
|
43
|
-
nokogiri (>= 1.8.5)
|
44
|
-
actionview (6.1.7.
|
45
|
-
activesupport (= 6.1.7.
|
46
|
-
builder (~> 3.1)
|
47
|
-
erubi (~> 1.4)
|
48
|
-
rails-dom-testing (~> 2.0)
|
49
|
-
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
50
|
-
activejob (6.1.7.
|
51
|
-
activesupport (= 6.1.7.
|
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.
|
63
|
-
marcel (~> 1.0)
|
64
|
-
mini_mime (>= 1.1.0)
|
65
|
-
activesupport (6.1.7.
|
66
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
67
|
-
i18n (>= 1.6, < 2)
|
68
|
-
minitest (>= 5.1)
|
69
|
-
tzinfo (~> 2.0)
|
70
|
-
zeitwerk (~> 2.3)
|
71
|
-
awesome_print (1.9.2)
|
72
|
-
builder (3.2.4)
|
73
|
-
concurrent-ruby (1.2.2)
|
74
|
-
crass (1.0.6)
|
75
|
-
date (3.3.3)
|
76
|
-
erubi (1.12.0)
|
77
|
-
globalid (1.1.0)
|
78
|
-
activesupport (>= 5.0)
|
79
|
-
i18n (1.
|
80
|
-
concurrent-ruby (~> 1.0)
|
81
|
-
loofah (2.
|
82
|
-
crass (~> 1.0.2)
|
83
|
-
nokogiri (>= 1.
|
84
|
-
mail (2.8.1)
|
85
|
-
mini_mime (>= 0.1.1)
|
86
|
-
net-imap
|
87
|
-
net-pop
|
88
|
-
net-smtp
|
89
|
-
marcel (1.0.2)
|
90
|
-
media_types (2.2
|
91
|
-
method_source (1.0.0)
|
92
|
-
mini_mime (1.1.
|
93
|
-
minitest (5.
|
94
|
-
net-imap (0.3.
|
95
|
-
date
|
96
|
-
net-protocol
|
97
|
-
net-pop (0.1.2)
|
98
|
-
net-protocol
|
99
|
-
net-protocol (0.2.1)
|
100
|
-
timeout
|
101
|
-
net-smtp (0.3.3)
|
102
|
-
net-protocol
|
103
|
-
nio4r (2.5.
|
104
|
-
nokogiri (1.
|
105
|
-
racc (~> 1.4)
|
106
|
-
oj (3.
|
107
|
-
racc (1.
|
108
|
-
rack (2.2.
|
109
|
-
rack-test (2.1.0)
|
110
|
-
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.
|
123
|
-
bundler (>= 1.15.0)
|
124
|
-
railties (= 6.1.7.
|
125
|
-
sprockets-rails (>= 2.0.0)
|
126
|
-
rails-dom-testing (2.0
|
127
|
-
activesupport (>=
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
websocket-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
media_types-serialization (2.0.4)
|
5
|
+
actionpack (>= 6.0.0)
|
6
|
+
activesupport (>= 6.0.0)
|
7
|
+
media_types (>= 2.2.3, < 3.0.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actioncable (6.1.7.4)
|
13
|
+
actionpack (= 6.1.7.4)
|
14
|
+
activesupport (= 6.1.7.4)
|
15
|
+
nio4r (~> 2.0)
|
16
|
+
websocket-driver (>= 0.6.1)
|
17
|
+
actionmailbox (6.1.7.4)
|
18
|
+
actionpack (= 6.1.7.4)
|
19
|
+
activejob (= 6.1.7.4)
|
20
|
+
activerecord (= 6.1.7.4)
|
21
|
+
activestorage (= 6.1.7.4)
|
22
|
+
activesupport (= 6.1.7.4)
|
23
|
+
mail (>= 2.7.1)
|
24
|
+
actionmailer (6.1.7.4)
|
25
|
+
actionpack (= 6.1.7.4)
|
26
|
+
actionview (= 6.1.7.4)
|
27
|
+
activejob (= 6.1.7.4)
|
28
|
+
activesupport (= 6.1.7.4)
|
29
|
+
mail (~> 2.5, >= 2.5.4)
|
30
|
+
rails-dom-testing (~> 2.0)
|
31
|
+
actionpack (6.1.7.4)
|
32
|
+
actionview (= 6.1.7.4)
|
33
|
+
activesupport (= 6.1.7.4)
|
34
|
+
rack (~> 2.0, >= 2.0.9)
|
35
|
+
rack-test (>= 0.6.3)
|
36
|
+
rails-dom-testing (~> 2.0)
|
37
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
38
|
+
actiontext (6.1.7.4)
|
39
|
+
actionpack (= 6.1.7.4)
|
40
|
+
activerecord (= 6.1.7.4)
|
41
|
+
activestorage (= 6.1.7.4)
|
42
|
+
activesupport (= 6.1.7.4)
|
43
|
+
nokogiri (>= 1.8.5)
|
44
|
+
actionview (6.1.7.4)
|
45
|
+
activesupport (= 6.1.7.4)
|
46
|
+
builder (~> 3.1)
|
47
|
+
erubi (~> 1.4)
|
48
|
+
rails-dom-testing (~> 2.0)
|
49
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
50
|
+
activejob (6.1.7.4)
|
51
|
+
activesupport (= 6.1.7.4)
|
52
|
+
globalid (>= 0.3.6)
|
53
|
+
activemodel (6.1.7.4)
|
54
|
+
activesupport (= 6.1.7.4)
|
55
|
+
activerecord (6.1.7.4)
|
56
|
+
activemodel (= 6.1.7.4)
|
57
|
+
activesupport (= 6.1.7.4)
|
58
|
+
activestorage (6.1.7.4)
|
59
|
+
actionpack (= 6.1.7.4)
|
60
|
+
activejob (= 6.1.7.4)
|
61
|
+
activerecord (= 6.1.7.4)
|
62
|
+
activesupport (= 6.1.7.4)
|
63
|
+
marcel (~> 1.0)
|
64
|
+
mini_mime (>= 1.1.0)
|
65
|
+
activesupport (6.1.7.4)
|
66
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
67
|
+
i18n (>= 1.6, < 2)
|
68
|
+
minitest (>= 5.1)
|
69
|
+
tzinfo (~> 2.0)
|
70
|
+
zeitwerk (~> 2.3)
|
71
|
+
awesome_print (1.9.2)
|
72
|
+
builder (3.2.4)
|
73
|
+
concurrent-ruby (1.2.2)
|
74
|
+
crass (1.0.6)
|
75
|
+
date (3.3.3)
|
76
|
+
erubi (1.12.0)
|
77
|
+
globalid (1.1.0)
|
78
|
+
activesupport (>= 5.0)
|
79
|
+
i18n (1.14.1)
|
80
|
+
concurrent-ruby (~> 1.0)
|
81
|
+
loofah (2.21.3)
|
82
|
+
crass (~> 1.0.2)
|
83
|
+
nokogiri (>= 1.12.0)
|
84
|
+
mail (2.8.1)
|
85
|
+
mini_mime (>= 0.1.1)
|
86
|
+
net-imap
|
87
|
+
net-pop
|
88
|
+
net-smtp
|
89
|
+
marcel (1.0.2)
|
90
|
+
media_types (2.3.2)
|
91
|
+
method_source (1.0.0)
|
92
|
+
mini_mime (1.1.5)
|
93
|
+
minitest (5.19.0)
|
94
|
+
net-imap (0.3.7)
|
95
|
+
date
|
96
|
+
net-protocol
|
97
|
+
net-pop (0.1.2)
|
98
|
+
net-protocol
|
99
|
+
net-protocol (0.2.1)
|
100
|
+
timeout
|
101
|
+
net-smtp (0.3.3)
|
102
|
+
net-protocol
|
103
|
+
nio4r (2.5.9)
|
104
|
+
nokogiri (1.15.4-x64-mingw32)
|
105
|
+
racc (~> 1.4)
|
106
|
+
oj (3.16.0)
|
107
|
+
racc (1.7.1)
|
108
|
+
rack (2.2.8)
|
109
|
+
rack-test (2.1.0)
|
110
|
+
rack (>= 1.3)
|
111
|
+
rails (6.1.7.4)
|
112
|
+
actioncable (= 6.1.7.4)
|
113
|
+
actionmailbox (= 6.1.7.4)
|
114
|
+
actionmailer (= 6.1.7.4)
|
115
|
+
actionpack (= 6.1.7.4)
|
116
|
+
actiontext (= 6.1.7.4)
|
117
|
+
actionview (= 6.1.7.4)
|
118
|
+
activejob (= 6.1.7.4)
|
119
|
+
activemodel (= 6.1.7.4)
|
120
|
+
activerecord (= 6.1.7.4)
|
121
|
+
activestorage (= 6.1.7.4)
|
122
|
+
activesupport (= 6.1.7.4)
|
123
|
+
bundler (>= 1.15.0)
|
124
|
+
railties (= 6.1.7.4)
|
125
|
+
sprockets-rails (>= 2.0.0)
|
126
|
+
rails-dom-testing (2.2.0)
|
127
|
+
activesupport (>= 5.0.0)
|
128
|
+
minitest
|
129
|
+
nokogiri (>= 1.6)
|
130
|
+
rails-html-sanitizer (1.6.0)
|
131
|
+
loofah (~> 2.21)
|
132
|
+
nokogiri (~> 1.14)
|
133
|
+
railties (6.1.7.4)
|
134
|
+
actionpack (= 6.1.7.4)
|
135
|
+
activesupport (= 6.1.7.4)
|
136
|
+
method_source
|
137
|
+
rake (>= 12.2)
|
138
|
+
thor (~> 1.0)
|
139
|
+
rake (13.0.6)
|
140
|
+
sprockets (4.2.0)
|
141
|
+
concurrent-ruby (~> 1.0)
|
142
|
+
rack (>= 2.2.4, < 4)
|
143
|
+
sprockets-rails (3.4.2)
|
144
|
+
actionpack (>= 5.2)
|
145
|
+
activesupport (>= 5.2)
|
146
|
+
sprockets (>= 3.0.0)
|
147
|
+
thor (1.2.2)
|
148
|
+
timeout (0.4.0)
|
149
|
+
tzinfo (2.0.6)
|
150
|
+
concurrent-ruby (~> 1.0)
|
151
|
+
websocket-driver (0.7.6)
|
152
|
+
websocket-extensions (>= 0.1.0)
|
153
|
+
websocket-extensions (0.1.5)
|
154
|
+
zeitwerk (2.6.11)
|
155
|
+
|
156
|
+
PLATFORMS
|
157
|
+
x64-mingw32
|
158
|
+
|
159
|
+
DEPENDENCIES
|
160
|
+
awesome_print
|
161
|
+
bundler
|
162
|
+
media_types-serialization!
|
163
|
+
minitest (~> 5.0)
|
164
|
+
oj
|
165
|
+
rails (~> 6.0)
|
166
|
+
rake (~> 13.0)
|
167
|
+
|
168
|
+
BUNDLED WITH
|
169
|
+
2.1.4
|
data/README.md
CHANGED
@@ -471,7 +471,7 @@ class BookController < ActionController::API
|
|
471
471
|
book = Book.new
|
472
472
|
book.title = 'Everything, abridged'
|
473
473
|
|
474
|
-
render_media
|
474
|
+
render_media book
|
475
475
|
end
|
476
476
|
|
477
477
|
def create
|
@@ -517,14 +517,14 @@ class BookController < ActionController::API
|
|
517
517
|
book = Book.new
|
518
518
|
book.title = 'Everything, abridged'
|
519
519
|
|
520
|
-
render_media
|
520
|
+
render_media book
|
521
521
|
end
|
522
522
|
|
523
523
|
def create
|
524
524
|
book = deserialize(request)
|
525
525
|
book.save!
|
526
526
|
|
527
|
-
render_media
|
527
|
+
render_media book
|
528
528
|
end
|
529
529
|
end
|
530
530
|
```
|
@@ -648,7 +648,7 @@ class BookController < ActionController::API
|
|
648
648
|
book = Book.new
|
649
649
|
book.title = 'Everything, abridged'
|
650
650
|
|
651
|
-
render_media
|
651
|
+
render_media book
|
652
652
|
end
|
653
653
|
|
654
654
|
def create
|
@@ -12,8 +12,8 @@ module MediaTypes
|
|
12
12
|
def unvalidated(prefix)
|
13
13
|
self.serializer_validated = false
|
14
14
|
self.serializer_validator = FakeValidator.new(prefix)
|
15
|
-
self.
|
16
|
-
self.
|
15
|
+
self.serializer_input_registrations = {}
|
16
|
+
self.serializer_output_registrations = {}
|
17
17
|
end
|
18
18
|
|
19
19
|
def validator(validator = nil)
|
@@ -22,8 +22,8 @@ module MediaTypes
|
|
22
22
|
|
23
23
|
self.serializer_validated = true
|
24
24
|
self.serializer_validator = validator
|
25
|
-
self.
|
26
|
-
self.
|
25
|
+
self.serializer_input_registrations = {}
|
26
|
+
self.serializer_output_registrations = {}
|
27
27
|
end
|
28
28
|
|
29
29
|
def disable_wildcards
|
@@ -40,11 +40,15 @@ module MediaTypes
|
|
40
40
|
|
41
41
|
raise ValidatorNotSpecifiedError, :output if serializer_validator.nil?
|
42
42
|
|
43
|
+
unless serializer_output_registrations.has_key? view
|
44
|
+
serializer_output_registrations[view] = SerializationRegistration.new(:output)
|
45
|
+
end
|
46
|
+
|
43
47
|
versions.each do |v|
|
44
48
|
validator = serializer_validator.view(view).version(v)
|
45
49
|
validator.override_suffix(:json) unless serializer_validated
|
46
50
|
|
47
|
-
|
51
|
+
serializer_output_registrations[view].register_block(
|
48
52
|
self,
|
49
53
|
validator,
|
50
54
|
v,
|
@@ -62,12 +66,16 @@ module MediaTypes
|
|
62
66
|
|
63
67
|
raise ValidatorNotSpecifiedError, :output if serializer_validator.nil?
|
64
68
|
|
69
|
+
unless serializer_output_registrations.has_key? view
|
70
|
+
serializer_output_registrations[view] = SerializationRegistration.new(:output)
|
71
|
+
end
|
72
|
+
|
65
73
|
versions.each do |v|
|
66
74
|
validator = serializer_validator.view(view)
|
67
75
|
.version(v)
|
68
76
|
.override_suffix(suffix)
|
69
77
|
|
70
|
-
|
78
|
+
serializer_output_registrations[view].register_block(
|
71
79
|
self,
|
72
80
|
validator,
|
73
81
|
v,
|
@@ -87,7 +95,11 @@ module MediaTypes
|
|
87
95
|
validator = serializer_validator.view(view).override_suffix(suffix)
|
88
96
|
victim_identifier = validator.identifier
|
89
97
|
|
90
|
-
|
98
|
+
unless serializer_output_registrations.has_key? view
|
99
|
+
serializer_output_registrations[view] = SerializationRegistration.new(:output)
|
100
|
+
end
|
101
|
+
|
102
|
+
serializer_output_registrations[view].register_alias(
|
91
103
|
self,
|
92
104
|
media_type_identifier,
|
93
105
|
victim_identifier,
|
@@ -106,7 +118,11 @@ module MediaTypes
|
|
106
118
|
validator = serializer_validator.view(view).override_suffix(suffix)
|
107
119
|
victim_identifier = validator.identifier
|
108
120
|
|
109
|
-
|
121
|
+
unless serializer_output_registrations.has_key? view
|
122
|
+
serializer_output_registrations[view] = SerializationRegistration.new(:output)
|
123
|
+
end
|
124
|
+
|
125
|
+
serializer_output_registrations[view].register_alias(
|
110
126
|
self,
|
111
127
|
media_type_identifier,
|
112
128
|
victim_identifier,
|
@@ -122,11 +138,15 @@ module MediaTypes
|
|
122
138
|
|
123
139
|
raise ValidatorNotSpecifiedError, :input if serializer_validator.nil?
|
124
140
|
|
141
|
+
unless serializer_input_registrations.has_key? view
|
142
|
+
serializer_input_registrations[view] = SerializationRegistration.new(:input)
|
143
|
+
end
|
144
|
+
|
125
145
|
versions.each do |v|
|
126
146
|
validator = serializer_validator.view(view).version(v)
|
127
147
|
validator.override_suffix(:json) unless serializer_validated
|
128
148
|
|
129
|
-
|
149
|
+
serializer_input_registrations[view].register_block(self, validator, v, block, false)
|
130
150
|
end
|
131
151
|
end
|
132
152
|
|
@@ -136,10 +156,14 @@ module MediaTypes
|
|
136
156
|
|
137
157
|
raise ValidatorNotSpecifiedError, :input if serializer_validator.nil?
|
138
158
|
|
159
|
+
unless serializer_input_registrations.has_key? view
|
160
|
+
serializer_input_registrations[view] = SerializationRegistration.new(:input)
|
161
|
+
end
|
162
|
+
|
139
163
|
versions.each do |v|
|
140
164
|
validator = serializer_validator.view(view).version(v).override_suffix(suffix)
|
141
165
|
|
142
|
-
|
166
|
+
serializer_input_registrations[view].register_block(self, validator, v, block, true)
|
143
167
|
end
|
144
168
|
end
|
145
169
|
|
@@ -151,7 +175,11 @@ module MediaTypes
|
|
151
175
|
validator = serializer_validator.view(view).override_suffix(suffix)
|
152
176
|
victim_identifier = validator.identifier
|
153
177
|
|
154
|
-
|
178
|
+
unless serializer_input_registrations.has_key? view
|
179
|
+
serializer_input_registrations[view] = SerializationRegistration.new(:input)
|
180
|
+
end
|
181
|
+
|
182
|
+
serializer_input_registrations[view].register_alias(
|
155
183
|
self,
|
156
184
|
media_type_identifier,
|
157
185
|
victim_identifier,
|
@@ -169,7 +197,11 @@ module MediaTypes
|
|
169
197
|
validator = serializer_validator.view(view).override_suffix(suffix)
|
170
198
|
victim_identifier = validator.identifier
|
171
199
|
|
172
|
-
|
200
|
+
unless serializer_input_registrations.has_key? view
|
201
|
+
serializer_input_registrations[view] = SerializationRegistration.new(:input)
|
202
|
+
end
|
203
|
+
|
204
|
+
serializer_input_registrations[view].register_alias(
|
173
205
|
self,
|
174
206
|
media_type_identifier,
|
175
207
|
victim_identifier,
|
@@ -181,19 +213,40 @@ module MediaTypes
|
|
181
213
|
|
182
214
|
def serialize(victim, media_type_identifier, context:, dsl: nil, raw: nil)
|
183
215
|
dsl ||= SerializationDSL.new(self, context: context)
|
184
|
-
|
216
|
+
|
217
|
+
merged_output_registrations = SerializationRegistration.new(:output)
|
218
|
+
serializer_output_registrations.keys.each do |k|
|
219
|
+
merged_output_registrations = merged_output_registrations.merge(serializer_output_registrations[k])
|
220
|
+
end
|
221
|
+
|
222
|
+
merged_output_registrations.call(victim, media_type_identifier.to_s, context, dsl: dsl, raw: raw)
|
185
223
|
end
|
186
224
|
|
187
225
|
def deserialize(victim, media_type_identifier, context:)
|
188
|
-
|
226
|
+
merged_input_registrations = SerializationRegistration.new(:input)
|
227
|
+
serializer_input_registrations.keys.each do |k|
|
228
|
+
merged_input_registrations = merged_input_registrations.merge(serializer_input_registrations[k])
|
229
|
+
end
|
230
|
+
|
231
|
+
merged_input_registrations.call(victim, media_type_identifier, context)
|
189
232
|
end
|
190
233
|
|
191
234
|
def outputs_for(views:)
|
192
|
-
|
235
|
+
merged_output_registrations = SerializationRegistration.new(:output)
|
236
|
+
views.each do |k|
|
237
|
+
merged_output_registrations = merged_output_registrations.merge(serializer_output_registrations[k]) if serializer_output_registrations.has_key?(k)
|
238
|
+
end
|
239
|
+
|
240
|
+
merged_output_registrations
|
193
241
|
end
|
194
242
|
|
195
243
|
def inputs_for(views:)
|
196
|
-
|
244
|
+
merged_input_registrations = SerializationRegistration.new(:input)
|
245
|
+
views.each do |k|
|
246
|
+
merged_input_registrations = merged_input_registrations.merge(serializer_input_registrations[k]) if serializer_input_registrations.has_key?(k)
|
247
|
+
end
|
248
|
+
|
249
|
+
merged_input_registrations
|
197
250
|
end
|
198
251
|
end
|
199
252
|
|
@@ -205,8 +258,8 @@ module MediaTypes
|
|
205
258
|
class << self
|
206
259
|
attr_accessor :serializer_validated
|
207
260
|
attr_accessor :serializer_validator
|
208
|
-
attr_accessor :
|
209
|
-
attr_accessor :
|
261
|
+
attr_accessor :serializer_input_registrations
|
262
|
+
attr_accessor :serializer_output_registrations
|
210
263
|
attr_accessor :serializer_disable_wildcards
|
211
264
|
end
|
212
265
|
end
|
@@ -168,14 +168,14 @@ module MediaTypes
|
|
168
168
|
if defined? Oj::ParseError
|
169
169
|
begin
|
170
170
|
victim = MediaTypes::Serialization.json_decoder.call(victim)
|
171
|
-
validator.validate!(victim)
|
171
|
+
validator.validate!(victim, loose: true)
|
172
172
|
rescue MediaTypes::Scheme::ValidationError, Oj::ParseError, JSON::ParserError, EncodingError => inner
|
173
173
|
raise InputValidationFailedError, inner
|
174
174
|
end
|
175
175
|
else
|
176
176
|
begin
|
177
177
|
victim = MediaTypes::Serialization.json_decoder.call(victim)
|
178
|
-
validator.validate!(victim)
|
178
|
+
validator.validate!(victim, loose: true)
|
179
179
|
rescue MediaTypes::Scheme::ValidationError, JSON::ParserError, EncodingError => inner
|
180
180
|
raise InputValidationFailedError, inner
|
181
181
|
end
|
@@ -22,6 +22,81 @@ module MediaTypes
|
|
22
22
|
viewer.to_s
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.to_input_identifiers(serializers)
|
26
|
+
serializers.flat_map do |s|
|
27
|
+
s[:serializer].inputs_for(views: [s[:view]]).registrations.keys
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def self.to_output_identifiers(serializers)
|
31
|
+
serializers.flat_map do |s|
|
32
|
+
s[:serializer].outputs_for(views: [s[:view]]).registrations.keys
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.allowed_replies(context, actions)
|
37
|
+
request_path = context.request.original_fullpath.split('?')[0]
|
38
|
+
|
39
|
+
path_prefix = ENV.fetch('RAILS_RELATIVE_URL_ROOT') { '' }
|
40
|
+
request_path = request_path.sub(path_prefix, '')
|
41
|
+
|
42
|
+
my_controller = Rails.application.routes.recognize_path request_path
|
43
|
+
possible_replies = ['POST', 'PUT', 'DELETE']
|
44
|
+
enabled_replies = {}
|
45
|
+
possible_replies.each do |m|
|
46
|
+
begin
|
47
|
+
found_controller = Rails.application.routes.recognize_path request_path, method: m
|
48
|
+
if found_controller[:controller] == my_controller[:controller]
|
49
|
+
enabled_replies[m] = found_controller[:action]
|
50
|
+
end
|
51
|
+
rescue ActionController::RoutingError
|
52
|
+
# not available
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
input_definitions = actions[:input] || {}
|
57
|
+
output_definitions = actions[:output] || {}
|
58
|
+
|
59
|
+
result = {}
|
60
|
+
global_in = input_definitions['all_actions'] || []
|
61
|
+
global_out = output_definitions['all_actions'] || []
|
62
|
+
|
63
|
+
viewer_uri = URI.parse(context.request.original_url)
|
64
|
+
query_parts = viewer_uri.query&.split('&') || []
|
65
|
+
query_parts = query_parts.select { |q| !q.start_with? 'api_viewer=' }
|
66
|
+
viewer_uri.query = (query_parts + ["api_viewer=last"]).join('&')
|
67
|
+
|
68
|
+
enabled_replies.each do |method, action|
|
69
|
+
input_serializers = global_in + (input_definitions[action] || [])
|
70
|
+
output_serializers = global_out + (output_definitions[action] || [])
|
71
|
+
result[method] = {
|
72
|
+
input: to_input_identifiers(input_serializers),
|
73
|
+
output: to_output_identifiers(output_serializers),
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.escape_javascript(value)
|
81
|
+
escape_map = {
|
82
|
+
"\\" => "\\\\",
|
83
|
+
"</" => '<\/',
|
84
|
+
"\r\n" => '\n',
|
85
|
+
"\n" => '\n',
|
86
|
+
"\r" => '\n',
|
87
|
+
'"' => '\\"',
|
88
|
+
"'" => "\\'",
|
89
|
+
"`" => "\\`",
|
90
|
+
"$" => "\\$"
|
91
|
+
}
|
92
|
+
escape_map[(+"\342\200\250").force_encoding(Encoding::UTF_8).encode!] = "
"
|
93
|
+
escape_map[(+"\342\200\251").force_encoding(Encoding::UTF_8).encode!] = "
"
|
94
|
+
|
95
|
+
value ||= ""
|
96
|
+
|
97
|
+
return value.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"']|[`]|[$])/u, escape_map).html_safe
|
98
|
+
end
|
99
|
+
|
25
100
|
output_raw do |obj, version, context|
|
26
101
|
original_identifier = obj[:identifier]
|
27
102
|
registrations = obj[:registrations]
|
@@ -71,15 +146,25 @@ module MediaTypes
|
|
71
146
|
end
|
72
147
|
&.join("<br>\n")
|
73
148
|
|
149
|
+
unviewered_uri = URI.parse(context.request.original_url)
|
150
|
+
query_parts = unviewered_uri.query&.split('&') || []
|
151
|
+
query_parts = query_parts.select { |q| !q.start_with? 'api_viewer=' }
|
152
|
+
unviewered_uri.query = query_parts.join('&')
|
153
|
+
|
74
154
|
input = OpenStruct.new(
|
75
155
|
original_identifier: original_identifier,
|
76
156
|
escaped_output: escaped_output,
|
77
157
|
api_fied_links: api_fied_links,
|
78
158
|
media_types: media_types,
|
79
|
-
css: CommonCSS.css
|
159
|
+
css: CommonCSS.css,
|
160
|
+
etag: obj[:etag],
|
161
|
+
allowed_replies: allowed_replies(context, obj[:actions]),
|
162
|
+
escape_javascript: method(:escape_javascript),
|
163
|
+
unviewered_uri: unviewered_uri
|
80
164
|
)
|
81
165
|
|
82
166
|
template = ERB.new <<-TEMPLATE
|
167
|
+
<!DOCTYPE html>
|
83
168
|
<html lang="en">
|
84
169
|
<head>
|
85
170
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
@@ -118,6 +203,168 @@ module MediaTypes
|
|
118
203
|
</ul>
|
119
204
|
</section>
|
120
205
|
</nav>
|
206
|
+
<% if allowed_replies.any? %>
|
207
|
+
<section id="reply">
|
208
|
+
<details>
|
209
|
+
<summary>Reply</summary>
|
210
|
+
<div class="reply-indent">
|
211
|
+
<noscript>Javascript is required to submit custom responses back to the server</noscript>
|
212
|
+
<form id="reply-form" hidden>
|
213
|
+
<div class="form-table">
|
214
|
+
<label class="form-row">
|
215
|
+
<div class="cell label">Method:</div>
|
216
|
+
<% if allowed_replies.keys.count == 1 %>
|
217
|
+
<input type="hidden" name="method" value="<%= allowed_replies.keys[0] %>">
|
218
|
+
<div class="cell"><%= allowed_replies.keys[0] %></div>
|
219
|
+
<% else %>
|
220
|
+
<select class="cell" name="method">
|
221
|
+
<% allowed_replies.keys.each do |method| %>
|
222
|
+
<option value="<%= method %>"><%= method %></option>
|
223
|
+
<% end %>
|
224
|
+
</select>
|
225
|
+
<% end %>
|
226
|
+
</label>
|
227
|
+
<label class="form-row"><div class="cell label">Send:</div> <select class="cell" name="request-content-type"></select></label>
|
228
|
+
<label class="form-row"><div class="cell label">Receive:</div> <select class="cell" name="response-content-type"></select></label>
|
229
|
+
</div>
|
230
|
+
<textarea name="request-content"></textarea>
|
231
|
+
<input type="button" name="submit" value="Reply"><span id="reply-status-code" hidden> - sending...</span>
|
232
|
+
<hr>
|
233
|
+
<code id="reply-response" hidden>
|
234
|
+
</code>
|
235
|
+
</form>
|
236
|
+
<script>
|
237
|
+
{
|
238
|
+
let form = document.getElementById("reply-form")
|
239
|
+
form.removeAttribute('hidden')
|
240
|
+
|
241
|
+
let action_data = JSON.parse("<%= escape_javascript.call(allowed_replies.to_json) %>")
|
242
|
+
|
243
|
+
let methodElem = form.elements["method"]
|
244
|
+
let requestTypeElem = form.elements["request-content-type"]
|
245
|
+
let responseTypeElem = form.elements["response-content-type"]
|
246
|
+
let contentElem = form.elements["request-content"]
|
247
|
+
let submitElem = form.elements["submit"]
|
248
|
+
let replyResponseElem = document.getElementById("reply-response")
|
249
|
+
let replyStatusCodeElem = document.getElementById("reply-status-code")
|
250
|
+
let selectRequestType = function() {
|
251
|
+
let selected = requestTypeElem.value
|
252
|
+
|
253
|
+
if (selected == "")
|
254
|
+
contentElem.setAttribute("hidden", "")
|
255
|
+
else
|
256
|
+
contentElem.removeAttribute("hidden")
|
257
|
+
|
258
|
+
if (methodElem.value == "PUT" && contentElem.value.trim() == "") {
|
259
|
+
let currentRequestType = document.querySelector("#representations .active").textContent.trim()
|
260
|
+
if (currentRequestType == requestTypeElem.value) {
|
261
|
+
let outputElem = document.getElementById("output")
|
262
|
+
contentElem.value = outputElem.
|
263
|
+
textContent.
|
264
|
+
trim().
|
265
|
+
replaceAll(String.fromCharCode(160), " ")
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
let selectMethod = function() {
|
271
|
+
let selected = methodElem.value
|
272
|
+
submitElem.setAttribute("value", selected)
|
273
|
+
|
274
|
+
let mediatypes = action_data[selected]
|
275
|
+
|
276
|
+
while(requestTypeElem.firstChild)
|
277
|
+
requestTypeElem.removeChild(requestTypeElem.lastChild)
|
278
|
+
mediatypes["input"].forEach(mediatype => {
|
279
|
+
let option = document.createElement("option")
|
280
|
+
option.setAttribute("value", mediatype)
|
281
|
+
option.textContent = mediatype
|
282
|
+
requestTypeElem.appendChild(option)
|
283
|
+
})
|
284
|
+
let noneOption = document.createElement("option")
|
285
|
+
noneOption.setAttribute("value", "")
|
286
|
+
noneOption.textContent = "None"
|
287
|
+
requestTypeElem.appendChild(noneOption)
|
288
|
+
|
289
|
+
while(responseTypeElem.firstChild)
|
290
|
+
responseTypeElem.removeChild(responseTypeElem.lastChild)
|
291
|
+
mediatypes["output"].forEach(mediatype => {
|
292
|
+
let option = document.createElement("option")
|
293
|
+
option.setAttribute("value", mediatype)
|
294
|
+
option.textContent = mediatype
|
295
|
+
responseTypeElem.appendChild(option)
|
296
|
+
})
|
297
|
+
let anyOption = document.createElement("option")
|
298
|
+
anyOption.setAttribute("value", "")
|
299
|
+
anyOption.textContent = "Any"
|
300
|
+
responseTypeElem.appendChild(anyOption)
|
301
|
+
|
302
|
+
selectRequestType()
|
303
|
+
}
|
304
|
+
|
305
|
+
let onSubmit = async function() {
|
306
|
+
submitElem.setAttribute("disabled", "")
|
307
|
+
let method = methodElem.value
|
308
|
+
let requestContentType = requestTypeElem.value
|
309
|
+
let requestContent = contentElem.value
|
310
|
+
var responseAccept = responseTypeElem.value + ", application/problem+json; q=0.2, */*; q=0.1"
|
311
|
+
if (responseTypeElem.value == "")
|
312
|
+
responseAccept = "application/problem+json, */*; q=0.1"
|
313
|
+
|
314
|
+
let headers = {
|
315
|
+
Accept: responseAccept,
|
316
|
+
}
|
317
|
+
if (method == "PUT") {
|
318
|
+
let etag = "<%= escape_javascript.call(etag) %>"
|
319
|
+
if (etag != "") {
|
320
|
+
headers['If-Match'] = etag
|
321
|
+
}
|
322
|
+
}
|
323
|
+
let body = undefined
|
324
|
+
if (requestContentType != "") {
|
325
|
+
headers["Content-Type"] = requestContentType
|
326
|
+
body = requestContent
|
327
|
+
}
|
328
|
+
|
329
|
+
replyResponseElem.textContent = ""
|
330
|
+
replyStatusCodeElem.textContent = " - sending..."
|
331
|
+
replyStatusCodeElem.removeAttribute("hidden")
|
332
|
+
|
333
|
+
try {
|
334
|
+
let response = await fetch("<%= escape_javascript.call(unviewered_uri.to_s) %>", {
|
335
|
+
method: method,
|
336
|
+
mode: "same-origin",
|
337
|
+
credentials: "same-origin",
|
338
|
+
redirect: "follow",
|
339
|
+
headers: headers,
|
340
|
+
body: body
|
341
|
+
})
|
342
|
+
|
343
|
+
replyStatusCodeElem.textContent = " - Status " + response.status + " " + response.statusText
|
344
|
+
replyResponseElem.removeAttribute("hidden")
|
345
|
+
replyResponseElem.textContent = await response.text()
|
346
|
+
replyResponseElem.innerHTML = replyResponseElem.
|
347
|
+
innerHTML.
|
348
|
+
replaceAll("\\n", "<br>\\n").
|
349
|
+
replaceAll(" ", " ")
|
350
|
+
} catch (error) {
|
351
|
+
replyStatusCodeElem.textContent = " - Failed: " + error.message
|
352
|
+
} finally {
|
353
|
+
submitElem.removeAttribute("disabled")
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
requestTypeElem.addEventListener("change", (e) => selectRequestType())
|
358
|
+
methodElem.addEventListener("change", (e) => selectMethod())
|
359
|
+
submitElem.addEventListener("click", (e) => onSubmit())
|
360
|
+
|
361
|
+
addEventListener("DOMContentLoaded", (event) => selectMethod());
|
362
|
+
}
|
363
|
+
</script>
|
364
|
+
</div>
|
365
|
+
</details>
|
366
|
+
</section>
|
367
|
+
<% end %>
|
121
368
|
<main>
|
122
369
|
<code id="output">
|
123
370
|
<%= escaped_output %>
|
@@ -49,65 +49,76 @@ module MediaTypes
|
|
49
49
|
min-height: 100%;
|
50
50
|
background: <%= background %>;
|
51
51
|
}
|
52
|
-
|
52
|
+
|
53
53
|
body {
|
54
54
|
color: #fff;
|
55
|
-
margin-left:
|
56
|
-
margin-right:
|
55
|
+
margin-left: 2em;
|
56
|
+
margin-right: 2em;
|
57
57
|
margin-top: 1em;
|
58
|
-
|
58
|
+
max-width: 1200px;
|
59
|
+
|
59
60
|
font-family: -apple-system, ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", sans-serif;
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
font-size: 16px;
|
62
|
+
line-height: 1.6;
|
63
|
+
-webkit-font-feature-settings: "kern","liga","clig","calt";
|
64
|
+
font-feature-settings: "kern","liga","clig","calt";
|
65
|
+
-webkit-font-smoothing: antialiased;
|
66
|
+
-moz-osx-font-smoothing: grayscale
|
67
|
+
overflow-x: hidden;
|
68
|
+
}
|
69
|
+
|
70
|
+
main {
|
71
|
+
max-width: 100%;
|
72
|
+
}
|
73
|
+
|
68
74
|
header {
|
69
75
|
display: inline-block;
|
76
|
+
max-width: 100%;
|
70
77
|
}
|
71
|
-
|
78
|
+
|
72
79
|
a:link {
|
73
|
-
color: #
|
80
|
+
color: #007bff;
|
74
81
|
}
|
75
82
|
a:visited {
|
76
|
-
color: #
|
83
|
+
color: #9c27b0;
|
77
84
|
}
|
78
85
|
a:hover {
|
79
|
-
color: #
|
86
|
+
color: #00bcd4;
|
80
87
|
}
|
81
|
-
|
88
|
+
|
82
89
|
#logo {
|
83
90
|
width: <%= logo_width %>em;
|
84
|
-
height:
|
85
|
-
|
86
|
-
|
87
|
-
|
91
|
+
height: 5em;
|
92
|
+
background-repeat: no-repeat;
|
93
|
+
background-position-x: right;
|
94
|
+
background-position-y: center;
|
88
95
|
background-image: url(<%= logo_url %>);
|
89
96
|
float: left;
|
90
|
-
margin-right:
|
97
|
+
margin-right: 2em;
|
91
98
|
}
|
92
|
-
|
99
|
+
|
93
100
|
header h1 {
|
94
101
|
clear: right;
|
95
102
|
text-overflow: ellipsis;
|
96
103
|
white-space: nowrap;
|
97
104
|
overflow: hidden;
|
105
|
+
|
106
|
+
font-size: 1.5em;
|
107
|
+
line-height: 2em;
|
98
108
|
}
|
99
|
-
|
109
|
+
|
100
110
|
#content {
|
101
111
|
margin-top: 1em;
|
102
|
-
padding-left:
|
103
|
-
padding-right:
|
104
|
-
padding-bottom:
|
112
|
+
padding-left: 1em;
|
113
|
+
padding-right: 1em;
|
114
|
+
padding-bottom: 1em;
|
105
115
|
color: #060B34;
|
106
116
|
background-color: #fff;
|
107
117
|
border-radius: 1em;
|
108
118
|
border: 1px solid #E0E1E4;
|
119
|
+
overflow: auto;
|
109
120
|
}
|
110
|
-
|
121
|
+
|
111
122
|
nav h2 {
|
112
123
|
font-size: 1em;
|
113
124
|
line-height: 1.25em;
|
@@ -116,7 +127,7 @@ module MediaTypes
|
|
116
127
|
nav .label {
|
117
128
|
float: left;
|
118
129
|
}
|
119
|
-
|
130
|
+
|
120
131
|
nav ul {
|
121
132
|
clear: right;
|
122
133
|
display: inline-block;
|
@@ -138,17 +149,15 @@ module MediaTypes
|
|
138
149
|
content: "|";
|
139
150
|
margin-right: 0.3em;
|
140
151
|
}
|
141
|
-
|
152
|
+
|
142
153
|
nav #representations {
|
143
|
-
margin-
|
144
|
-
margin-right: -2em;
|
145
|
-
margin-bottom: 2em;
|
154
|
+
margin-bottom: 1em;
|
146
155
|
}
|
147
156
|
nav hr {
|
148
157
|
border: none;
|
149
158
|
border-top: solid 1px #E0E1E4;
|
150
159
|
}
|
151
|
-
|
160
|
+
|
152
161
|
nav #links {
|
153
162
|
display: inline-block;
|
154
163
|
margin-bottom: 1em;
|
@@ -156,7 +165,42 @@ module MediaTypes
|
|
156
165
|
nav #links ul {
|
157
166
|
float: left;
|
158
167
|
}
|
168
|
+
|
169
|
+
#output {
|
170
|
+
font-size: .9em;
|
171
|
+
}
|
172
|
+
|
173
|
+
#reply .reply-indent {
|
174
|
+
border-left: 0.5em solid lightgray;
|
175
|
+
padding-left: 1em;
|
176
|
+
}
|
177
|
+
|
178
|
+
#reply .form-table {
|
179
|
+
display: table;
|
180
|
+
border-spacing: 1em 0;
|
181
|
+
margin-left: -1em;
|
182
|
+
margin-bottom: 0.2em;
|
183
|
+
}
|
184
|
+
|
185
|
+
#reply .form-row {
|
186
|
+
display: table-row;
|
187
|
+
}
|
159
188
|
|
189
|
+
#reply .cell {
|
190
|
+
display: table-cell;
|
191
|
+
}
|
192
|
+
|
193
|
+
#reply textarea {
|
194
|
+
width: 100%;
|
195
|
+
height: 6em;
|
196
|
+
clear: both;
|
197
|
+
}
|
198
|
+
|
199
|
+
#reply #reply-status-code {
|
200
|
+
font-style: italic;
|
201
|
+
font-size: 80%;
|
202
|
+
}
|
203
|
+
|
160
204
|
TEMPLATE
|
161
205
|
template = ERB.new custom_css unless custom_css.nil?
|
162
206
|
|
@@ -195,12 +195,14 @@ module MediaTypes
|
|
195
195
|
|
196
196
|
validator = FakeValidator.new(as.nil? ? 'text/html' : as)
|
197
197
|
|
198
|
-
block = lambda { |
|
198
|
+
block = lambda { |victim, _, controller|
|
199
199
|
options = {}
|
200
200
|
options[:layout] = layout unless layout.nil?
|
201
201
|
options[:template] = view unless view.nil?
|
202
202
|
options[:formats] = formats unless formats.nil?
|
203
203
|
options[:variants] = variants unless variants.nil?
|
204
|
+
options[:locals] = victim if victim.is_a?(::Hash)
|
205
|
+
options[:assigns] = { media: victim }
|
204
206
|
|
205
207
|
controller.render_to_string(**options)
|
206
208
|
}
|
@@ -445,9 +447,12 @@ module MediaTypes
|
|
445
447
|
@serialization_override_accept = registration.registrations.keys.last
|
446
448
|
end
|
447
449
|
|
448
|
-
return
|
450
|
+
return @serialization_override_accept if registration.has? @serialization_override_accept
|
449
451
|
|
450
|
-
|
452
|
+
# Always render problems in api viewer if we can't show chosen override
|
453
|
+
return 'application/problem+json' if registration.has? 'application/problem+json'
|
454
|
+
|
455
|
+
return nil
|
451
456
|
end
|
452
457
|
|
453
458
|
# Ruby negotiation
|
@@ -536,10 +541,14 @@ module MediaTypes
|
|
536
541
|
self
|
537
542
|
)
|
538
543
|
rescue InputValidationFailedError => e
|
539
|
-
serializers = @serialization_input_validation_failed_serializer
|
540
|
-
|
541
|
-
|
542
|
-
|
544
|
+
serializers = if defined?(@serialization_input_validation_failed_serializer)
|
545
|
+
@serialization_input_validation_failed_serializer
|
546
|
+
else
|
547
|
+
[
|
548
|
+
MediaTypes::Serialization::Serializers::ProblemSerializer,
|
549
|
+
MediaTypes::Serialization::Serializers::InputValidationErrorSerializer
|
550
|
+
]
|
551
|
+
end
|
543
552
|
registrations = SerializationRegistration.new(:output)
|
544
553
|
serializers.each do |s|
|
545
554
|
registrations = registrations.merge(s.outputs_for(views: [nil, :html]))
|
@@ -551,7 +560,7 @@ module MediaTypes
|
|
551
560
|
error: e
|
552
561
|
}
|
553
562
|
|
554
|
-
render_media nil, serializers: [registrations], status: :
|
563
|
+
render_media nil, serializers: [registrations], status: :bad_request do
|
555
564
|
serializer MediaTypes::Serialization::Serializers::InputValidationErrorSerializer, input
|
556
565
|
serializer MediaTypes::Serialization::Serializers::ProblemSerializer do
|
557
566
|
problem = Problem.new(e)
|
@@ -577,7 +586,7 @@ module MediaTypes
|
|
577
586
|
|
578
587
|
endpoint_matched_identifier = resolve_media_type(
|
579
588
|
request,
|
580
|
-
description_serializer.
|
589
|
+
description_serializer.serializer_output_registrations[nil],
|
581
590
|
allow_last: false
|
582
591
|
)
|
583
592
|
|
@@ -654,7 +663,9 @@ module MediaTypes
|
|
654
663
|
identifier: identifier,
|
655
664
|
registrations: registrations,
|
656
665
|
output: result,
|
657
|
-
links: links
|
666
|
+
links: links,
|
667
|
+
etag: response.get_header('ETag'),
|
668
|
+
actions: @serialization_available_serializers
|
658
669
|
}
|
659
670
|
wrapped = @serialization_wrapping_renderer.serialize input, '*/*', context: self
|
660
671
|
render body: wrapped
|
@@ -664,6 +675,9 @@ module MediaTypes
|
|
664
675
|
end
|
665
676
|
|
666
677
|
if context.serialization_custom_render.nil?
|
678
|
+
status = options.delete(:status)
|
679
|
+
response.status = status if status
|
680
|
+
|
667
681
|
render body: result, **options
|
668
682
|
|
669
683
|
response.content_type = registrations.identifier_for(identifier)
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
|
38
38
|
spec.add_dependency 'actionpack', '>= 6.0.0'
|
39
39
|
spec.add_dependency 'activesupport', '>= 6.0.0'
|
40
|
-
spec.add_dependency 'media_types', '>= 2.2.
|
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'
|
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:
|
4
|
+
version: 2.0.4
|
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: 2023-
|
12
|
+
date: 2023-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 2.2.
|
48
|
+
version: 2.2.3
|
49
49
|
- - "<"
|
50
50
|
- !ruby/object:Gem::Version
|
51
51
|
version: 3.0.0
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
requirements:
|
56
56
|
- - ">="
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: 2.2.
|
58
|
+
version: 2.2.3
|
59
59
|
- - "<"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 3.0.0
|
@@ -152,6 +152,8 @@ extensions: []
|
|
152
152
|
extra_rdoc_files: []
|
153
153
|
files:
|
154
154
|
- ".github/workflows/ci.yml"
|
155
|
+
- ".github/workflows/publish-bookworm.yml"
|
156
|
+
- ".github/workflows/publish-sid.yml"
|
155
157
|
- ".gitignore"
|
156
158
|
- ".idea/.rakeTasks"
|
157
159
|
- ".idea/dictionaries/Derk_Jan.xml"
|