haveapi 0.18.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/haveapi.gemspec +2 -1
- data/lib/haveapi/action.rb +72 -31
- data/lib/haveapi/authentication/base.rb +1 -1
- data/lib/haveapi/authentication/basic/provider.rb +2 -2
- data/lib/haveapi/authentication/chain.rb +4 -4
- data/lib/haveapi/authentication/oauth2/config.rb +62 -15
- data/lib/haveapi/authentication/oauth2/provider.rb +111 -17
- data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +36 -0
- data/lib/haveapi/authentication/token/config.rb +1 -0
- data/lib/haveapi/authorization.rb +19 -12
- data/lib/haveapi/client_examples/js_client.rb +11 -1
- data/lib/haveapi/client_examples/php_client.rb +43 -1
- data/lib/haveapi/context.rb +21 -2
- data/lib/haveapi/example.rb +9 -9
- data/lib/haveapi/hooks.rb +23 -23
- data/lib/haveapi/metadata.rb +1 -1
- data/lib/haveapi/model_adapter.rb +14 -14
- data/lib/haveapi/model_adapters/active_record.rb +20 -20
- data/lib/haveapi/output_formatter.rb +4 -4
- data/lib/haveapi/output_formatters/base.rb +1 -1
- data/lib/haveapi/parameters/resource.rb +22 -22
- data/lib/haveapi/parameters/typed.rb +7 -7
- data/lib/haveapi/params.rb +24 -22
- data/lib/haveapi/resource.rb +9 -3
- data/lib/haveapi/resources/action_state.rb +16 -16
- data/lib/haveapi/route.rb +3 -2
- data/lib/haveapi/server.rb +113 -98
- data/lib/haveapi/spec/mock_action.rb +7 -7
- data/lib/haveapi/spec/spec_methods.rb +8 -8
- data/lib/haveapi/tasks/yard.rb +2 -2
- data/lib/haveapi/validator.rb +13 -13
- data/lib/haveapi/validator_chain.rb +6 -6
- data/lib/haveapi/validators/acceptance.rb +2 -2
- data/lib/haveapi/validators/confirmation.rb +4 -4
- data/lib/haveapi/validators/exclusion.rb +4 -4
- data/lib/haveapi/validators/format.rb +4 -4
- data/lib/haveapi/validators/inclusion.rb +3 -3
- data/lib/haveapi/validators/length.rb +1 -1
- data/lib/haveapi/validators/numericality.rb +3 -3
- data/lib/haveapi/validators/presence.rb +2 -2
- data/lib/haveapi/version.rb +1 -1
- data/lib/haveapi/views/version_page/auth_body.erb +6 -4
- data/lib/haveapi/views/version_page/resource_body.erb +2 -0
- data/lib/haveapi.rb +1 -0
- data/spec/authorization_spec.rb +28 -28
- data/spec/envelope_spec.rb +4 -4
- data/spec/parameters/typed_spec.rb +3 -3
- data/spec/params_spec.rb +2 -2
- data/spec/validators/acceptance_spec.rb +2 -2
- data/spec/validators/confirmation_spec.rb +4 -4
- data/spec/validators/exclusion_spec.rb +2 -2
- data/spec/validators/format_spec.rb +5 -5
- data/spec/validators/inclusion_spec.rb +8 -8
- data/spec/validators/presence_spec.rb +1 -1
- metadata +19 -4
@@ -1,20 +1,27 @@
|
|
1
1
|
module HaveAPI
|
2
2
|
class Authorization
|
3
3
|
def initialize(&block)
|
4
|
-
@
|
4
|
+
@blocks = [block]
|
5
5
|
end
|
6
6
|
|
7
7
|
# Returns true if user is authorized.
|
8
8
|
# Block must call allow to authorize user, default rule is deny.
|
9
|
-
def authorized?(user)
|
9
|
+
def authorized?(user, path_params)
|
10
10
|
@restrict = []
|
11
11
|
|
12
12
|
catch(:rule) do
|
13
|
-
|
14
|
-
|
13
|
+
@blocks.each do |block|
|
14
|
+
instance_exec(user, path_params, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
deny # will not be called if some block throws allow
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
21
|
+
def prepend_block(block)
|
22
|
+
@blocks.insert(0, block)
|
23
|
+
end
|
24
|
+
|
18
25
|
# Apply restrictions on query which selects objects from database.
|
19
26
|
# Most common usage is restrict user to access only objects he owns.
|
20
27
|
def restrict(**kwargs)
|
@@ -22,22 +29,22 @@ module HaveAPI
|
|
22
29
|
end
|
23
30
|
|
24
31
|
# Restrict parameters client can set/change.
|
25
|
-
# [
|
26
|
-
# [
|
32
|
+
# @param whitelist [Array<Symbol>] allow only listed parameters
|
33
|
+
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
27
34
|
def input(whitelist: nil, blacklist: nil)
|
28
35
|
@input = {
|
29
|
-
|
30
|
-
|
36
|
+
whitelist: whitelist,
|
37
|
+
blacklist: blacklist,
|
31
38
|
}
|
32
39
|
end
|
33
40
|
|
34
41
|
# Restrict parameters client can retrieve.
|
35
|
-
# [
|
36
|
-
# [
|
42
|
+
# @param whitelist [Array<Symbol>] allow only listed parameters
|
43
|
+
# @param blacklist [Array<Symbol>] allow all parameters except listed ones
|
37
44
|
def output(whitelist: nil, blacklist: nil)
|
38
45
|
@output = {
|
39
|
-
|
40
|
-
|
46
|
+
whitelist: whitelist,
|
47
|
+
blacklist: blacklist,
|
41
48
|
}
|
42
49
|
end
|
43
50
|
|
@@ -51,7 +51,17 @@ api.authenticate("token", {
|
|
51
51
|
END
|
52
52
|
|
53
53
|
when :oauth2
|
54
|
-
|
54
|
+
<<END
|
55
|
+
#{init}
|
56
|
+
// The JavaScript client must be configured with OAuth2 access token, it does not
|
57
|
+
// support the authorization procedure to obtain a new access token.
|
58
|
+
var accessToken = {
|
59
|
+
access_token: "the access token"
|
60
|
+
};
|
61
|
+
|
62
|
+
// The client is authenticated immediately, no need for a callback
|
63
|
+
api.authenticate("oauth2", {access_token: accessToken});
|
64
|
+
END
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
@@ -35,7 +35,49 @@ $api->authenticate("token", ["token" => $savedToken]);
|
|
35
35
|
END
|
36
36
|
|
37
37
|
when :oauth2
|
38
|
-
|
38
|
+
<<END
|
39
|
+
// OAuth2 requires session
|
40
|
+
session_start();
|
41
|
+
|
42
|
+
// Client instance
|
43
|
+
#{init}
|
44
|
+
// Check if we already have an access token
|
45
|
+
if (isset($_SESSION["access_token"])) {
|
46
|
+
// We're already authenticated, reuse the existing access token
|
47
|
+
$api->authenticate("oauth2", ["access_token" => $_SESSION["access_token"]]);
|
48
|
+
|
49
|
+
} else {
|
50
|
+
// Follow the OAuth2 authorization process to get an access token using
|
51
|
+
// authorization code
|
52
|
+
$api->authenticate("oauth2", [
|
53
|
+
// Client id and secret are given by the API server
|
54
|
+
"client_id" => "your client id",
|
55
|
+
"client_secret" => "your client secret",
|
56
|
+
|
57
|
+
// This example code should run on the URL below
|
58
|
+
"redirect_uri" => "https://your-client.tld/oauth2-callback",
|
59
|
+
|
60
|
+
// Scopes are specific to the API implementation
|
61
|
+
"scope" => "all",
|
62
|
+
]);
|
63
|
+
|
64
|
+
$provider = $api->getAuthenticationProvider();
|
65
|
+
|
66
|
+
// We don't have authorization code yet, request one
|
67
|
+
if (!isset($_GET['code'])) {
|
68
|
+
// Redirect the user to the authorization endpoint
|
69
|
+
$provider->requestAuthorizationCode();
|
70
|
+
exit;
|
71
|
+
|
72
|
+
} else {
|
73
|
+
// Request access token using the token endpoint
|
74
|
+
$provider->requestAccessToken();
|
75
|
+
|
76
|
+
// Store the access token in the session
|
77
|
+
$_SESSION['access_token'] = $provider->jsonSerialize();
|
78
|
+
}
|
79
|
+
}
|
80
|
+
END
|
39
81
|
end
|
40
82
|
end
|
41
83
|
|
data/lib/haveapi/context.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module HaveAPI
|
2
2
|
class Context
|
3
3
|
attr_accessor :server, :version, :request, :resource, :action, :path, :args,
|
4
|
-
:params, :current_user, :authorization, :endpoint,
|
4
|
+
:params, :current_user, :authorization, :endpoint, :resource_path,
|
5
5
|
:action_instance, :action_prepare, :layout
|
6
6
|
|
7
7
|
def initialize(server, version: nil, request: nil, resource: [], action: nil,
|
8
8
|
path: nil, args: nil, params: nil, user: nil,
|
9
|
-
authorization: nil, endpoint: nil)
|
9
|
+
authorization: nil, endpoint: nil, resource_path: [])
|
10
10
|
@server = server
|
11
11
|
@version = version
|
12
12
|
@request = request
|
@@ -18,6 +18,7 @@ module HaveAPI
|
|
18
18
|
@current_user = user
|
19
19
|
@authorization = authorization
|
20
20
|
@endpoint = endpoint
|
21
|
+
@resource_path = resource_path
|
21
22
|
end
|
22
23
|
|
23
24
|
def resolved_path
|
@@ -71,6 +72,24 @@ module HaveAPI
|
|
71
72
|
path_for(action, call_path_params(action, obj))
|
72
73
|
end
|
73
74
|
|
75
|
+
def path_params_from_args
|
76
|
+
ret = {}
|
77
|
+
return ret if args.nil?
|
78
|
+
|
79
|
+
my_args = args.clone
|
80
|
+
|
81
|
+
path.scan(/\{([a-zA-Z\-_]+)\}/) do |match|
|
82
|
+
path_param = match.first
|
83
|
+
ret[path_param] = my_args.shift
|
84
|
+
end
|
85
|
+
|
86
|
+
ret
|
87
|
+
end
|
88
|
+
|
89
|
+
def action_scope
|
90
|
+
resource_path.map(&:downcase).join('.') + '#' + action.action_name.underscore
|
91
|
+
end
|
92
|
+
|
74
93
|
private
|
75
94
|
def resolve_arg!(path, arg)
|
76
95
|
path.sub!(/\{[a-zA-Z\-_]+\}/, arg.to_s)
|
data/lib/haveapi/example.rb
CHANGED
@@ -58,15 +58,15 @@ module HaveAPI
|
|
58
58
|
def describe(context)
|
59
59
|
if provided?
|
60
60
|
{
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
title: @title,
|
62
|
+
comment: @comment,
|
63
|
+
path_params: @path_params,
|
64
|
+
request: filter_input_params(context, @request),
|
65
|
+
response: filter_output_params(context, @response),
|
66
|
+
status: @status.nil? ? true : @status,
|
67
|
+
message: @message,
|
68
|
+
errors: @errors,
|
69
|
+
http_status: @http_status || 200,
|
70
70
|
}
|
71
71
|
else
|
72
72
|
{}
|
data/lib/haveapi/hooks.rb
CHANGED
@@ -79,15 +79,15 @@ module HaveAPI
|
|
79
79
|
module Hooks
|
80
80
|
INSTANCE_VARIABLE = '@_haveapi_hooks'
|
81
81
|
|
82
|
-
# Register a hook defined by
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
82
|
+
# Register a hook defined by `klass` with `name`.
|
83
|
+
# @param klass [Class] an instance of Class, that is class name, not it's instance
|
84
|
+
# @param opts [Hash]
|
85
|
+
# @option opts [String] :desc why this hook exists, when it's called
|
86
|
+
# @option opts [String] :context the context in which given blocks are called
|
87
|
+
# @option opts [Hash] :args hash of block positional arguments
|
88
|
+
# @option opts [Hash] :kwargs hash of block keyword arguments
|
89
|
+
# @option opts [Hash] :initial - hash of initial values
|
90
|
+
# @option opts [Hash] :ret hash of return values
|
91
91
|
def self.register_hook(klass, name, opts = {})
|
92
92
|
classified = hook_classify(klass)
|
93
93
|
opts[:listeners] = []
|
@@ -101,13 +101,13 @@ module HaveAPI
|
|
101
101
|
@hooks
|
102
102
|
end
|
103
103
|
|
104
|
-
# Connect class hook defined in
|
105
|
-
#
|
104
|
+
# Connect class hook defined in `klass` with `name` to `block`.
|
105
|
+
# `klass` is a class name.
|
106
106
|
def self.connect_hook(klass, name, &block)
|
107
107
|
@hooks[hook_classify(klass)][name][:listeners] << block
|
108
108
|
end
|
109
109
|
|
110
|
-
# Connect instance hook from instance
|
110
|
+
# Connect instance hook from instance `klass` with `name` to `block`.
|
111
111
|
def self.connect_instance_hook(instance, name, &block)
|
112
112
|
hooks = instance.instance_variable_get(INSTANCE_VARIABLE)
|
113
113
|
|
@@ -120,11 +120,11 @@ module HaveAPI
|
|
120
120
|
hooks[name][:listeners] << block
|
121
121
|
end
|
122
122
|
|
123
|
-
# Call all blocks that are connected to hook in
|
123
|
+
# Call all blocks that are connected to hook in `klass` with `name`.
|
124
124
|
# +klass+ may be a class name or an object instance.
|
125
|
-
# If
|
126
|
-
#
|
127
|
-
# to all block is always a return value from previous block or
|
125
|
+
# If `where` is set, the blocks are executed in it with instance_exec.
|
126
|
+
# `args` is an array of arguments given to all blocks. The first argument
|
127
|
+
# to all block is always a return value from previous block or `initial`,
|
128
128
|
# which defaults to an empty hash.
|
129
129
|
#
|
130
130
|
# Blocks are executed one by one in the order they were connected.
|
@@ -193,17 +193,17 @@ module HaveAPI
|
|
193
193
|
# Classes that define hooks must include this module.
|
194
194
|
module Hookable
|
195
195
|
module ClassMethods
|
196
|
-
# Register a hook named
|
196
|
+
# Register a hook named `name`.
|
197
197
|
def has_hook(name, opts = {})
|
198
198
|
Hooks.register_hook(self.to_s, name, opts)
|
199
199
|
end
|
200
200
|
|
201
|
-
# Connect
|
201
|
+
# Connect `block` to registered hook with `name`.
|
202
202
|
def connect_hook(name, &block)
|
203
203
|
Hooks.connect_hook(self.to_s, name, &block)
|
204
204
|
end
|
205
205
|
|
206
|
-
# Call all hooks for
|
206
|
+
# Call all hooks for `name`. see {Hooks.call_for}.
|
207
207
|
def call_hooks(*args, **kwargs)
|
208
208
|
Hooks.call_for(self.to_s, *args, **kwargs)
|
209
209
|
end
|
@@ -228,7 +228,7 @@ module HaveAPI
|
|
228
228
|
Hooks.call_for(self.class, name, where, args: args, kwargs: kwargs, initial: initial)
|
229
229
|
end
|
230
230
|
|
231
|
-
# Call hooks for different
|
231
|
+
# Call hooks for different `klass`.
|
232
232
|
def call_hooks_as_for(klass, *args, **kwargs)
|
233
233
|
ret = call_instance_hooks_as_for(klass, *args, **kwargs)
|
234
234
|
|
@@ -236,17 +236,17 @@ module HaveAPI
|
|
236
236
|
call_class_hooks_as_for(klass.class, *args, **kwargs)
|
237
237
|
end
|
238
238
|
|
239
|
-
# Call only instance hooks for different
|
239
|
+
# Call only instance hooks for different `klass`.
|
240
240
|
def call_instance_hooks_as_for(klass, *args, **kwargs)
|
241
241
|
Hooks.call_for(klass, *args, **kwargs)
|
242
242
|
end
|
243
243
|
|
244
|
-
# Call only class hooks for different
|
244
|
+
# Call only class hooks for different `klass`.
|
245
245
|
def call_class_hooks_as_for(klass, *args, **kwargs)
|
246
246
|
Hooks.call_for(klass, *args, **kwargs)
|
247
247
|
end
|
248
248
|
|
249
|
-
# Connect instance level hook
|
249
|
+
# Connect instance level hook `name` to `block`.
|
250
250
|
def connect_hook(name, &block)
|
251
251
|
Hooks.connect_instance_hook(self, name, &block)
|
252
252
|
end
|
data/lib/haveapi/metadata.rb
CHANGED
@@ -2,8 +2,8 @@ module HaveAPI
|
|
2
2
|
# Model adapters are used to automate handling of action
|
3
3
|
# input/output.
|
4
4
|
#
|
5
|
-
# Adapters are chosen based on the
|
6
|
-
# If no
|
5
|
+
# Adapters are chosen based on the `model` set on a HaveAPI::Resource.
|
6
|
+
# If no `model` is specified, ModelAdapters::Hash is used as a default
|
7
7
|
# adapter.
|
8
8
|
#
|
9
9
|
# All model adapters are based on this class.
|
@@ -17,7 +17,7 @@ module HaveAPI
|
|
17
17
|
ModelAdapter.adapters << Kernel.const_get(self.to_s)
|
18
18
|
end
|
19
19
|
|
20
|
-
# Returns an adapter suitable for
|
20
|
+
# Returns an adapter suitable for `layout` and `obj`.
|
21
21
|
# Adapters are iterated over and the first to return true to handle?()
|
22
22
|
# is returned.
|
23
23
|
def for(layout, obj)
|
@@ -41,21 +41,21 @@ module HaveAPI
|
|
41
41
|
self::Output.new(*args)
|
42
42
|
end
|
43
43
|
|
44
|
-
# Override this method to load validators from
|
45
|
-
# to
|
44
|
+
# Override this method to load validators from `model`
|
45
|
+
# to `params`.
|
46
46
|
def load_validators(model, params)
|
47
47
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# Called when mounting the API. Model adapters may use this method
|
51
|
-
# to add custom meta parameters to
|
52
|
-
#
|
51
|
+
# to add custom meta parameters to `action`. `direction` is one of
|
52
|
+
# `:input` and `:output`.
|
53
53
|
def used_by(direction, action)
|
54
54
|
case direction
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
when :input
|
56
|
+
self::Input.used_by(action)
|
57
|
+
when :output
|
58
|
+
self::Output.used_by(action)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -72,12 +72,12 @@ module HaveAPI
|
|
72
72
|
end
|
73
73
|
|
74
74
|
# Return true if input parameters contain parameter
|
75
|
-
# with
|
75
|
+
# with `name`.
|
76
76
|
def has_param?(name)
|
77
77
|
@input.has_key?(name)
|
78
78
|
end
|
79
79
|
|
80
|
-
# Return parameter with
|
80
|
+
# Return parameter with `name`.
|
81
81
|
def [](name)
|
82
82
|
@input[name]
|
83
83
|
end
|
@@ -101,7 +101,7 @@ module HaveAPI
|
|
101
101
|
end
|
102
102
|
|
103
103
|
# Return true if input parameters contain parameter
|
104
|
-
# with
|
104
|
+
# with `name`.
|
105
105
|
def has_param?(name)
|
106
106
|
|
107
107
|
end
|
@@ -21,7 +21,7 @@ module HaveAPI::ModelAdapters
|
|
21
21
|
module InstanceMethods
|
22
22
|
# Helper method that sets correct ActiveRecord includes
|
23
23
|
# according to the meta includes sent by the user.
|
24
|
-
#
|
24
|
+
# `q` is the model or partial AR query. If not set,
|
25
25
|
# action's model class is used instead.
|
26
26
|
def with_includes(q = nil)
|
27
27
|
q ||= self.class.model
|
@@ -179,14 +179,14 @@ END
|
|
179
179
|
end
|
180
180
|
|
181
181
|
{
|
182
|
-
|
183
|
-
|
182
|
+
path_params: params.is_a?(Array) ? params : [params],
|
183
|
+
resolved: true
|
184
184
|
}
|
185
185
|
end
|
186
186
|
|
187
187
|
protected
|
188
|
-
# Return representation of an associated resource
|
189
|
-
# with its instance in
|
188
|
+
# Return representation of an associated resource `param`
|
189
|
+
# with its instance in `val`.
|
190
190
|
#
|
191
191
|
# By default, it returns an unresolved resource, which contains
|
192
192
|
# only object id and label. Resource will be resolved
|
@@ -204,11 +204,11 @@ END
|
|
204
204
|
pass_includes = includes_pass_on_to(param.name)
|
205
205
|
|
206
206
|
show = res_show.new(
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
207
|
+
push_ins.request,
|
208
|
+
push_ins.version,
|
209
|
+
{},
|
210
|
+
nil,
|
211
|
+
@context
|
212
212
|
)
|
213
213
|
show.meta[:includes] = pass_includes
|
214
214
|
|
@@ -231,17 +231,17 @@ END
|
|
231
231
|
|
232
232
|
else
|
233
233
|
{
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
234
|
+
param.value_id => val.send(res_output[param.value_id].db_name),
|
235
|
+
param.value_label => val.send(res_output[param.value_label].db_name),
|
236
|
+
_meta: {
|
237
|
+
:path_params => args.is_a?(Array) ? args : [args],
|
238
|
+
:resolved => false
|
239
|
+
}
|
240
240
|
}
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
244
|
-
# Should an association with
|
244
|
+
# Should an association with `name` be resolved?
|
245
245
|
def includes_include?(name)
|
246
246
|
includes = @context.action_instance.meta[:includes]
|
247
247
|
return unless includes
|
@@ -324,7 +324,7 @@ END
|
|
324
324
|
|
325
325
|
handle ::ActiveModel::Validations::ExclusionValidator do |v|
|
326
326
|
opts = {
|
327
|
-
|
327
|
+
values: v.options[:in].map { |v| v }
|
328
328
|
}
|
329
329
|
opts[:message] = v.options[:message] if v.options[:message]
|
330
330
|
|
@@ -333,7 +333,7 @@ END
|
|
333
333
|
|
334
334
|
handle ::ActiveModel::Validations::FormatValidator do |v|
|
335
335
|
opts = {
|
336
|
-
|
336
|
+
rx: v.options[:with]
|
337
337
|
}
|
338
338
|
opts[:message] = v.options[:message] if v.options[:message]
|
339
339
|
|
@@ -342,7 +342,7 @@ END
|
|
342
342
|
|
343
343
|
handle ::ActiveModel::Validations::InclusionValidator do |v|
|
344
344
|
opts = {
|
345
|
-
|
345
|
+
values: v.options[:in].map { |v| v }
|
346
346
|
}
|
347
347
|
opts[:message] = v.options[:message] if v.options[:message]
|
348
348
|
|
@@ -49,10 +49,10 @@ module HaveAPI
|
|
49
49
|
ret = {}
|
50
50
|
ret[:version] = HaveAPI::PROTOCOL_VERSION if version
|
51
51
|
ret.update({
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
status: status,
|
53
|
+
response: response,
|
54
|
+
message: message,
|
55
|
+
errors: errors
|
56
56
|
})
|
57
57
|
ret
|
58
58
|
end
|
@@ -43,35 +43,35 @@ module HaveAPI::Parameters
|
|
43
43
|
|
44
44
|
def describe(context)
|
45
45
|
val_path = context.path_for(
|
46
|
-
|
47
|
-
|
46
|
+
@resource::Show,
|
47
|
+
context.endpoint && context.action_prepare && context.layout == :object && context.call_path_params(context.action, context.action_prepare)
|
48
48
|
)
|
49
49
|
val_method = @resource::Index.http_method.to_s.upcase
|
50
50
|
|
51
51
|
choices_path = context.path_for(
|
52
|
-
|
53
|
-
|
52
|
+
@choices,
|
53
|
+
context.endpoint && context.layout == :object && context.call_path_params(context.action, context.action_prepare)
|
54
54
|
)
|
55
55
|
choices_method = @choices.http_method.to_s.upcase
|
56
56
|
|
57
57
|
{
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
58
|
+
required: required?,
|
59
|
+
label: @label,
|
60
|
+
description: @desc,
|
61
|
+
type: 'Resource',
|
62
|
+
resource: @resource_path,
|
63
|
+
value_id: @value_id,
|
64
|
+
value_label: @value_label,
|
65
|
+
value: context.action_prepare && {
|
66
|
+
path: val_path,
|
67
|
+
method: val_method,
|
68
|
+
help: "#{val_path}?method=#{val_method}",
|
69
|
+
},
|
70
|
+
choices: {
|
71
|
+
path: choices_path,
|
72
|
+
method: choices_method,
|
73
|
+
help: "#{choices_path}?method=#{choices_method}"
|
74
|
+
}
|
75
75
|
}
|
76
76
|
end
|
77
77
|
|
@@ -93,7 +93,7 @@ module HaveAPI::Parameters
|
|
93
93
|
|
94
94
|
def clean(raw)
|
95
95
|
::HaveAPI::ModelAdapter.for(
|
96
|
-
|
96
|
+
show_action.input.layout, @resource.model
|
97
97
|
).input_clean(@resource.model, raw, @extra)
|
98
98
|
end
|
99
99
|
|
@@ -46,13 +46,13 @@ module HaveAPI::Parameters
|
|
46
46
|
|
47
47
|
def describe(context)
|
48
48
|
{
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
required: required?,
|
50
|
+
label: @label,
|
51
|
+
description: @desc,
|
52
|
+
type: @type ? @type.to_s : String.to_s,
|
53
|
+
validators: @validators ? @validators.describe : {},
|
54
|
+
default: @default,
|
55
|
+
protected: @protected || false,
|
56
56
|
}
|
57
57
|
end
|
58
58
|
|