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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '096826bd7e4a4be4fcd147fec07f26d05aec0101b8651ae63ed376a7a2388077'
4
- data.tar.gz: 2f783986be7ca3eff779e10a2ace5338d9ab7dbb755334ae79d01d7b422a77c9
3
+ metadata.gz: 693624dcfef405aa51599edfecb2eb6d355d4e33b2ed862cae84da2ba38d1184
4
+ data.tar.gz: c6ef94f5cf139da3c4699fd15f4322b5417ca2840b62038b0c96580d6b3afed4
5
5
  SHA512:
6
- metadata.gz: f0b58cdb8eb8e4f8c0c8ad73cc607673768cba38399cf9c804db16a54198b3fe0799a18c641e7c05d10e03c2936fc96a416b80ff51ff4bd5e6d570b10a47e712
7
- data.tar.gz: e82051321d55df89abe34c6d43e62a0158245c4fb9ae60060fc3e939df854626b3014285f2ac277f7632f6c3cd099ef349265bdfffbf7b7b226f76287bb53147
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*.gem
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 (1.4.0)
5
- actionpack (>= 6.0.0)
6
- activesupport (>= 6.0.0)
7
- media_types (>= 2.2.0, < 3.0.0)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actioncable (6.1.7.3)
13
- actionpack (= 6.1.7.3)
14
- activesupport (= 6.1.7.3)
15
- nio4r (~> 2.0)
16
- websocket-driver (>= 0.6.1)
17
- actionmailbox (6.1.7.3)
18
- actionpack (= 6.1.7.3)
19
- activejob (= 6.1.7.3)
20
- activerecord (= 6.1.7.3)
21
- activestorage (= 6.1.7.3)
22
- activesupport (= 6.1.7.3)
23
- mail (>= 2.7.1)
24
- actionmailer (6.1.7.3)
25
- actionpack (= 6.1.7.3)
26
- actionview (= 6.1.7.3)
27
- activejob (= 6.1.7.3)
28
- activesupport (= 6.1.7.3)
29
- mail (~> 2.5, >= 2.5.4)
30
- rails-dom-testing (~> 2.0)
31
- actionpack (6.1.7.3)
32
- actionview (= 6.1.7.3)
33
- activesupport (= 6.1.7.3)
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.3)
39
- actionpack (= 6.1.7.3)
40
- activerecord (= 6.1.7.3)
41
- activestorage (= 6.1.7.3)
42
- activesupport (= 6.1.7.3)
43
- nokogiri (>= 1.8.5)
44
- actionview (6.1.7.3)
45
- activesupport (= 6.1.7.3)
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.3)
51
- activesupport (= 6.1.7.3)
52
- globalid (>= 0.3.6)
53
- activemodel (6.1.7.3)
54
- activesupport (= 6.1.7.3)
55
- activerecord (6.1.7.3)
56
- activemodel (= 6.1.7.3)
57
- activesupport (= 6.1.7.3)
58
- activestorage (6.1.7.3)
59
- actionpack (= 6.1.7.3)
60
- activejob (= 6.1.7.3)
61
- activerecord (= 6.1.7.3)
62
- activesupport (= 6.1.7.3)
63
- marcel (~> 1.0)
64
- mini_mime (>= 1.1.0)
65
- activesupport (6.1.7.3)
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.12.0)
80
- concurrent-ruby (~> 1.0)
81
- loofah (2.19.1)
82
- crass (~> 1.0.2)
83
- nokogiri (>= 1.5.9)
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.0)
91
- method_source (1.0.0)
92
- mini_mime (1.1.2)
93
- minitest (5.18.0)
94
- net-imap (0.3.4)
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.8)
104
- nokogiri (1.14.2-x64-mingw32)
105
- racc (~> 1.4)
106
- oj (3.14.2)
107
- racc (1.6.2)
108
- rack (2.2.6.4)
109
- rack-test (2.1.0)
110
- rack (>= 1.3)
111
- rails (6.1.7.3)
112
- actioncable (= 6.1.7.3)
113
- actionmailbox (= 6.1.7.3)
114
- actionmailer (= 6.1.7.3)
115
- actionpack (= 6.1.7.3)
116
- actiontext (= 6.1.7.3)
117
- actionview (= 6.1.7.3)
118
- activejob (= 6.1.7.3)
119
- activemodel (= 6.1.7.3)
120
- activerecord (= 6.1.7.3)
121
- activestorage (= 6.1.7.3)
122
- activesupport (= 6.1.7.3)
123
- bundler (>= 1.15.0)
124
- railties (= 6.1.7.3)
125
- sprockets-rails (>= 2.0.0)
126
- rails-dom-testing (2.0.3)
127
- activesupport (>= 4.2.0)
128
- nokogiri (>= 1.6)
129
- rails-html-sanitizer (1.5.0)
130
- loofah (~> 2.19, >= 2.19.1)
131
- railties (6.1.7.3)
132
- actionpack (= 6.1.7.3)
133
- activesupport (= 6.1.7.3)
134
- method_source
135
- rake (>= 12.2)
136
- thor (~> 1.0)
137
- rake (13.0.6)
138
- sprockets (4.2.0)
139
- concurrent-ruby (~> 1.0)
140
- rack (>= 2.2.4, < 4)
141
- sprockets-rails (3.4.2)
142
- actionpack (>= 5.2)
143
- activesupport (>= 5.2)
144
- sprockets (>= 3.0.0)
145
- thor (1.2.1)
146
- timeout (0.3.2)
147
- tzinfo (2.0.6)
148
- concurrent-ruby (~> 1.0)
149
- websocket-driver (0.7.5)
150
- websocket-extensions (>= 0.1.0)
151
- websocket-extensions (0.1.5)
152
- zeitwerk (2.6.7)
153
-
154
- PLATFORMS
155
- x64-mingw32
156
-
157
- DEPENDENCIES
158
- awesome_print
159
- bundler
160
- media_types-serialization!
161
- minitest (~> 5.0)
162
- oj
163
- rails (~> 6.0)
164
- rake (~> 13.0)
165
-
166
- BUNDLED WITH
167
- 2.1.4
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 serialize_media(book)
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 serialize_media(book)
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 serialize_media(book)
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 serialize_media(book)
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.serializer_input_registration = SerializationRegistration.new(:input)
16
- self.serializer_output_registration = SerializationRegistration.new(:output)
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.serializer_input_registration = SerializationRegistration.new(:input)
26
- self.serializer_output_registration = SerializationRegistration.new(:output)
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
- serializer_output_registration.register_block(
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
- serializer_output_registration.register_block(
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
- serializer_output_registration.register_alias(
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
- serializer_output_registration.register_alias(
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
- serializer_input_registration.register_block(self, validator, v, block, false)
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
- serializer_input_registration.register_block(self, validator, v, block, true)
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
- serializer_input_registration.register_alias(
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
- serializer_input_registration.register_alias(
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
- serializer_output_registration.call(victim, media_type_identifier.to_s, context, dsl: dsl, raw: raw)
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
- serializer_input_registration.call(victim, media_type_identifier, context)
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
- serializer_output_registration.filter(views: views)
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
- serializer_input_registration.filter(views: views)
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 :serializer_input_registration
209
- attr_accessor :serializer_output_registration
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!] = "&#x2028;"
93
+ escape_map[(+"\342\200\251").force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
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(" ", "&nbsp; ")
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: 10em;
56
- margin-right: 10em;
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
- font-size: 16px;
61
- line-height: 1.6;
62
- -webkit-font-feature-settings: "kern","liga","clig","calt";
63
- font-feature-settings: "kern","liga","clig","calt";
64
- -webkit-font-smoothing: antialiased;
65
- -moz-osx-font-smoothing: grayscale
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: #293590;
80
+ color: #007bff;
74
81
  }
75
82
  a:visited {
76
- color: #080F43;
83
+ color: #9c27b0;
77
84
  }
78
85
  a:hover {
79
- color: #5E7EFF;
86
+ color: #00bcd4;
80
87
  }
81
-
88
+
82
89
  #logo {
83
90
  width: <%= logo_width %>em;
84
- height: 6em;
85
- background-repeat: no-repeat;
86
- background-position-x: right;
87
- background-position-y: center;
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: 0.75em;
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: 3em;
103
- padding-right: 3em;
104
- padding-bottom: 3em;
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-left: -2em;
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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module MediaTypes
4
4
  module Serialization
5
- VERSION = '1.4.0'
5
+ VERSION = '2.0.4'
6
6
  end
7
7
  end
@@ -195,12 +195,14 @@ module MediaTypes
195
195
 
196
196
  validator = FakeValidator.new(as.nil? ? 'text/html' : as)
197
197
 
198
- block = lambda { |_, _, controller|
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 nil unless registration.has? @serialization_override_accept
450
+ return @serialization_override_accept if registration.has? @serialization_override_accept
449
451
 
450
- return @serialization_override_accept
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
- MediaTypes::Serialization::Serializers::ProblemSerializer,
541
- MediaTypes::Serialization::Serializers::InputValidationErrorSerializer
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: :unprocessable_entity do
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.serializer_output_registration,
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.0', '< 3.0.0'
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: 1.4.0
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-03-24 00:00:00.000000000 Z
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.0
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.0
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"