toast 1.0.8 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/toast.rb +12 -3
- data/lib/toast/config_dsl/base.rb +15 -3
- data/lib/toast/errors.rb +3 -0
- data/lib/toast/rack_app.rb +10 -9
- data/lib/toast/request_helpers.rb +13 -9
- data/lib/toast/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 013c0b6f57e6509f8555a3bb9a4886e1abaf3f33
|
4
|
+
data.tar.gz: 317ecb00aeaff9b9c7e3faf0271119e956d96075
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f14236d4f0d9d5bb2f4959c36e759bf2d51b1509dbd31b1b4c2560fa31c2a8cbe90c335e73b533fecc7c95bf8588cedcef1681f858ff4694b9ce1f6e45a9b3ee
|
7
|
+
data.tar.gz: 8cdb9770f943e081eb7e9d099de3214cb7ab167dc25558162ae0300beb05cfabd29b0508c891cdd3a8d0aa3a9a94b827bf0769b05a4392256d586d477aad16fa
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@ Other features are:
|
|
20
20
|
* attribute selection per request
|
21
21
|
* processing of URI parameters
|
22
22
|
|
23
|
-
See the [User Manual](https://
|
23
|
+
See the [User Manual](https://robert-annies.github.io/toast) for a detailed description.
|
24
24
|
|
25
25
|
Releases
|
26
26
|
========
|
data/lib/toast.rb
CHANGED
@@ -15,7 +15,7 @@ module Toast
|
|
15
15
|
# path tree to resolve the requested model
|
16
16
|
@@path_tree = {}
|
17
17
|
|
18
|
-
cattr_accessor :expositions, :settings, :path_tree
|
18
|
+
cattr_accessor :expositions, :settings, :path_tree, :request
|
19
19
|
|
20
20
|
class ConfigError < StandardError
|
21
21
|
end
|
@@ -59,7 +59,7 @@ module Toast
|
|
59
59
|
|
60
60
|
def self.info str
|
61
61
|
if Rails.const_defined?('Server') # only on console server
|
62
|
-
puts Toast::Sym+' Toast: '+str
|
62
|
+
puts Toast::Sym+' Toast: '+str
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -82,7 +82,7 @@ module Toast
|
|
82
82
|
# base_uri must be passed to be prepended in URIs
|
83
83
|
def self.represent instance, base_uri = ''
|
84
84
|
|
85
|
-
# using RequestHelper#represent_one method with a mocked up object
|
85
|
+
# using RequestHelper#represent_one method with a mocked up object :-/
|
86
86
|
obj = Object.new
|
87
87
|
class << obj
|
88
88
|
include Toast::RequestHelpers
|
@@ -91,4 +91,13 @@ module Toast
|
|
91
91
|
obj.base_uri = base_uri
|
92
92
|
obj.represent_one(instance, obj.get_config(instance.class) )
|
93
93
|
end
|
94
|
+
|
95
|
+
def self.base_uri
|
96
|
+
raise Toast::NotInRequestContext unless request
|
97
|
+
|
98
|
+
port = ":#{request.port}" unless request.port.in?([80,443])
|
99
|
+
# remove recource path part form full path (namespace remains)
|
100
|
+
path = request.path.sub(request.path_parameters[:toast_path],'')
|
101
|
+
(request.protocol + request.host + port.to_s + path).chomp('/')
|
102
|
+
end
|
94
103
|
end
|
@@ -20,11 +20,14 @@ class Toast::ConfigDSL::Base
|
|
20
20
|
raise_config_error 'Block expected.'
|
21
21
|
end
|
22
22
|
|
23
|
+
|
24
|
+
|
25
|
+
|
23
26
|
# register base path with 'under' prefix
|
24
|
-
to_path_tree = lambda do |path|
|
27
|
+
to_path_tree = lambda do |path|
|
25
28
|
if path.empty?
|
26
29
|
{ model_class.to_s.underscore.pluralize => model_class }
|
27
|
-
else
|
30
|
+
else
|
28
31
|
{ path.first => to_path_tree.call(path[1..-1]) }
|
29
32
|
end
|
30
33
|
end
|
@@ -34,6 +37,15 @@ class Toast::ConfigDSL::Base
|
|
34
37
|
raise_config_error "multiple definitions of endpoint URI segment `.../#{key}/...'"
|
35
38
|
end
|
36
39
|
|
40
|
+
# externd model_class with toast_uri accessor
|
41
|
+
model_class.send(:define_method, :toast_full_uri) do
|
42
|
+
Toast.base_uri + '/' + self.toast_local_uri
|
43
|
+
end
|
44
|
+
|
45
|
+
model_class.send(:define_method, :toast_local_uri) do
|
46
|
+
[path, self.class.name.underscore.pluralize, self.id].delete_if(&:blank?).join('/')
|
47
|
+
end
|
48
|
+
|
37
49
|
# base config object
|
38
50
|
config_data = OpenStruct.new
|
39
51
|
|
@@ -43,7 +55,7 @@ class Toast::ConfigDSL::Base
|
|
43
55
|
self.model_class = model_class
|
44
56
|
self.media_type = as
|
45
57
|
self.prefix_path = path
|
46
|
-
|
58
|
+
|
47
59
|
# defaults
|
48
60
|
self.readables = []
|
49
61
|
self.writables = []
|
data/lib/toast/errors.rb
CHANGED
data/lib/toast/rack_app.rb
CHANGED
@@ -6,7 +6,7 @@ require 'toast/plural_assoc_request'
|
|
6
6
|
require 'toast/errors'
|
7
7
|
|
8
8
|
class Toast::RackApp
|
9
|
-
# NOTE: the RackApp object is shared in threads of concurrent requests
|
9
|
+
# NOTE: the RackApp object is shared in threads of concurrent requests
|
10
10
|
# (e.g. when using Puma server, but not in Passenger (single-threded, multi-process)).
|
11
11
|
# Anyays, don't use any instance vars (@ variables in #call).
|
12
12
|
# It causes chaos
|
@@ -16,17 +16,18 @@ class Toast::RackApp
|
|
16
16
|
def call(env)
|
17
17
|
|
18
18
|
request = ActionDispatch::Request.new(env)
|
19
|
-
|
19
|
+
Toast.request = request
|
20
|
+
|
20
21
|
Toast.logger.info "[#{Thread.current.object_id}] processing: <#{URI.decode(request.fullpath)}>"
|
21
22
|
|
22
|
-
# Authentication: respond with 401 on exception or falsy return value:
|
23
|
+
# Authentication: respond with 401 on exception or falsy return value:
|
23
24
|
begin
|
24
25
|
unless (auth = Toast::ConfigDSL::Settings::AuthenticateContext.new.
|
25
26
|
instance_exec(request, &Toast.settings.authenticate))
|
26
27
|
return response :unauthorized, msg: "authentication failed"
|
27
28
|
end
|
28
|
-
rescue Toast::Errors::CustomAuthFailure => caf
|
29
|
-
return response(caf.response_data[:status] || :unauthorized,
|
29
|
+
rescue Toast::Errors::CustomAuthFailure => caf
|
30
|
+
return response(caf.response_data[:status] || :unauthorized,
|
30
31
|
msg: caf.response_data[:body],
|
31
32
|
headers: caf.response_data[:headers])
|
32
33
|
rescue => error
|
@@ -34,7 +35,7 @@ class Toast::RackApp
|
|
34
35
|
end
|
35
36
|
|
36
37
|
path = request.path_parameters[:toast_path].split('/')
|
37
|
-
|
38
|
+
|
38
39
|
# look up requested model
|
39
40
|
model_class = resolve_model(path, Toast.path_tree)
|
40
41
|
|
@@ -120,15 +121,15 @@ class Toast::RackApp
|
|
120
121
|
end
|
121
122
|
|
122
123
|
private
|
123
|
-
# gets the model class from the
|
124
|
+
# gets the model class from the
|
124
125
|
# it's similar to Hash#dig but stops at a non string
|
125
126
|
def resolve_model path, path_tree
|
126
|
-
if path_tree[ path.first ].is_a?(Hash)
|
127
|
+
if path_tree[ path.first ].is_a?(Hash)
|
127
128
|
# dig deeper
|
128
129
|
resolve_model(path[1..-1], path_tree[ path.first ])
|
129
130
|
else
|
130
131
|
path_tree[ path.first ]
|
131
132
|
end
|
132
|
-
end
|
133
|
+
end
|
133
134
|
end
|
134
135
|
|
@@ -8,13 +8,8 @@ module Toast::RequestHelpers
|
|
8
8
|
end || raise(Toast::Errors::ConfigNotFound)
|
9
9
|
end
|
10
10
|
|
11
|
-
# this is hard when behind a proxy
|
12
|
-
# relies on HTTP_X_FORWARDED* headers
|
13
11
|
def base_uri request
|
14
|
-
|
15
|
-
# remove recource path part form full path (namespace remains)
|
16
|
-
path = request.path.sub(request.path_parameters[:toast_path],'')
|
17
|
-
(request.protocol + request.host + port.to_s + path).chomp('/')
|
12
|
+
Toast.base_uri
|
18
13
|
end
|
19
14
|
|
20
15
|
# split the name and id of the resource from a LinkHeader
|
@@ -25,12 +20,21 @@ module Toast::RequestHelpers
|
|
25
20
|
def represent_one record, config
|
26
21
|
result = {}
|
27
22
|
|
23
|
+
model_uri = [@base_uri, config.prefix_path, record.class.name.underscore.pluralize].delete_if(&:blank?).join('/')
|
24
|
+
|
25
|
+
# can we inject model_uri into the recortd, so that virtual attribute methods can use it in their result?
|
26
|
+
|
27
|
+
# - setting a special property on the record :-/, OK Toast could extend all exposed classes by a special accessor,
|
28
|
+
# maybe only if configured.
|
29
|
+
# - calling somehow this method in different/extended context (how?)
|
30
|
+
# - passing this as parameter, while not requiring all the attribute methods to accept a 2. arg (possible?)
|
31
|
+
# - If the result is a String it can return a templated String like "{{ toast_uri }}", OK for single
|
32
|
+
# strings, but for mebedded Hashes with Strings no, too expensive.
|
33
|
+
|
28
34
|
(config.readables + config.writables).each do |attr|
|
29
35
|
result[attr.to_s] = record.send(attr) if attr_selected?(attr)
|
30
36
|
end
|
31
37
|
|
32
|
-
model_uri = [@base_uri, config.prefix_path, record.class.name.underscore.pluralize].delete_if(&:blank?).join('/')
|
33
|
-
|
34
38
|
result['self'] = "#{model_uri}/#{record.id}" if attr_selected?('self')
|
35
39
|
|
36
40
|
# add associations, collections and singles
|
@@ -127,7 +131,7 @@ module Toast::RequestHelpers
|
|
127
131
|
rescue Toast::Errors::BadRequest
|
128
132
|
raise # re-raise
|
129
133
|
rescue => error
|
130
|
-
raise Toast::Errors::HandlerError.new(error, error.backtrace.first.sub
|
134
|
+
raise Toast::Errors::HandlerError.new(error, error.backtrace.first.try(:sub,/:in.*/,''))
|
131
135
|
end
|
132
136
|
result
|
133
137
|
end
|
data/lib/toast/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- robokopp (Robert Annies)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|