haveapi 0.28.4 → 0.29.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/README.md +139 -0
- data/Rakefile +1 -0
- data/haveapi.gemspec +2 -1
- data/lib/haveapi/action.rb +26 -9
- data/lib/haveapi/actions/default.rb +5 -2
- data/lib/haveapi/actions/paginable.rb +8 -4
- data/lib/haveapi/authentication/oauth2/provider.rb +1 -1
- data/lib/haveapi/authentication/token/config.rb +10 -3
- data/lib/haveapi/authentication/token/provider.rb +22 -21
- data/lib/haveapi/context.rb +4 -1
- data/lib/haveapi/i18n.rb +125 -0
- data/lib/haveapi/locales/cs.yml +167 -0
- data/lib/haveapi/locales/en.yml +168 -0
- data/lib/haveapi/metadata.rb +25 -3
- data/lib/haveapi/model_adapters/active_record.rb +40 -26
- data/lib/haveapi/output_formatter.rb +2 -2
- data/lib/haveapi/parameters/metadata_i18n.rb +179 -0
- data/lib/haveapi/parameters/resource.rb +18 -7
- data/lib/haveapi/parameters/typed.rb +27 -20
- data/lib/haveapi/params.rb +76 -7
- data/lib/haveapi/resource.rb +1 -1
- data/lib/haveapi/resources/action_state.rb +47 -27
- data/lib/haveapi/server.rb +156 -16
- data/lib/haveapi/spec/api_builder.rb +25 -0
- data/lib/haveapi/spec/spec_methods.rb +10 -0
- data/lib/haveapi/tasks/i18n.rb +198 -0
- data/lib/haveapi/validator_chain.rb +1 -1
- data/lib/haveapi/validators/acceptance.rb +5 -2
- data/lib/haveapi/validators/confirmation.rb +5 -2
- data/lib/haveapi/validators/exclusion.rb +2 -2
- data/lib/haveapi/validators/format.rb +5 -2
- data/lib/haveapi/validators/inclusion.rb +2 -2
- data/lib/haveapi/validators/length.rb +5 -5
- data/lib/haveapi/validators/numericality.rb +20 -22
- data/lib/haveapi/validators/presence.rb +4 -2
- data/lib/haveapi/version.rb +1 -1
- data/lib/haveapi.rb +1 -0
- data/spec/authentication/oauth2_spec.rb +10 -0
- data/spec/i18n_spec.rb +520 -0
- data/spec/params_spec.rb +183 -0
- metadata +29 -3
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# This file is generated from i18n/haveapi.yml.
|
|
2
|
+
# Do not edit it manually; manual changes will be overwritten.
|
|
3
|
+
# Update i18n/haveapi.yml and run bundle exec rake i18n:update.
|
|
4
|
+
---
|
|
5
|
+
cs:
|
|
6
|
+
haveapi:
|
|
7
|
+
action_state:
|
|
8
|
+
cancellation_failed: zrušení selhalo
|
|
9
|
+
not_found: stav akce nebyl nalezen
|
|
10
|
+
timeout_max: timeout může být nejvýše %{max}
|
|
11
|
+
authentication:
|
|
12
|
+
failed: přihlášení selhalo
|
|
13
|
+
invalid_credentials: neplatné přihlašovací údaje
|
|
14
|
+
multiple_oauth2_tokens: Bylo poskytnuto více OAuth2 tokenů
|
|
15
|
+
multiple_tokens: Bylo poskytnuto více ověřovacích tokenů
|
|
16
|
+
renew_failed: obnovení selhalo
|
|
17
|
+
required: Akce vyžaduje přihlášení uživatele
|
|
18
|
+
revoke_failed: zrušení selhalo
|
|
19
|
+
token_required: Akce vyžaduje přihlášení uživatele tokenem
|
|
20
|
+
authorization:
|
|
21
|
+
insufficient_permissions: Přístup odepřen. Nedostatečná oprávnění.
|
|
22
|
+
errors:
|
|
23
|
+
action_not_found: Akce nebyla nalezena
|
|
24
|
+
bad_accept_header: Chybná hlavička Accept
|
|
25
|
+
bad_json_syntax: Chybná syntaxe JSON
|
|
26
|
+
json_body_object: Tělo JSON musí být objekt
|
|
27
|
+
server_error: Došlo k chybě serveru
|
|
28
|
+
unsupported_content_type: Nepodporovaný Content-Type
|
|
29
|
+
pagination:
|
|
30
|
+
limit_max: limit může být nejvýše %{max}
|
|
31
|
+
parameters:
|
|
32
|
+
action_state:
|
|
33
|
+
can_cancel:
|
|
34
|
+
description: Je-li true, spuštění této akce lze zrušit
|
|
35
|
+
label: Lze zrušit
|
|
36
|
+
created_at:
|
|
37
|
+
label: Vytvořeno
|
|
38
|
+
current:
|
|
39
|
+
label: Aktuální průběh
|
|
40
|
+
finished:
|
|
41
|
+
label: Dokončeno
|
|
42
|
+
label:
|
|
43
|
+
label: Popisek
|
|
44
|
+
poll:
|
|
45
|
+
current:
|
|
46
|
+
description: průběh, se kterým se porovnává při nastaveném update_in
|
|
47
|
+
status:
|
|
48
|
+
description: stav, se kterým se porovnává při nastaveném update_in
|
|
49
|
+
timeout:
|
|
50
|
+
description: v sekundách
|
|
51
|
+
label: Časový limit
|
|
52
|
+
total:
|
|
53
|
+
description: průběh, se kterým se porovnává při nastaveném update_in
|
|
54
|
+
update_in:
|
|
55
|
+
description: počet sekund, po kterém se stav vrátí, pokud se průběh změnil
|
|
56
|
+
label: Průběh
|
|
57
|
+
status:
|
|
58
|
+
description: Určuje, zda akce probíhá nebo selhává
|
|
59
|
+
label: Stav
|
|
60
|
+
total:
|
|
61
|
+
description: Akce je dokončena, když se aktuální průběh rovná celkovému
|
|
62
|
+
label: Celkem
|
|
63
|
+
unit:
|
|
64
|
+
description: Jednotka aktuálního a celkového průběhu
|
|
65
|
+
label: Jednotka
|
|
66
|
+
updated_at:
|
|
67
|
+
description: Kdy byl průběh naposledy aktualizován
|
|
68
|
+
label: Aktualizováno
|
|
69
|
+
action_state_id:
|
|
70
|
+
description: ID objektu ActionState pro dotazování stavu. Pokud je null, akce
|
|
71
|
+
není pro aktuální volání blokující.
|
|
72
|
+
label: ID stavu akce
|
|
73
|
+
active_record:
|
|
74
|
+
includes:
|
|
75
|
+
description: |-
|
|
76
|
+
Seznam názvů asociovaných prostředků oddělených čárkou.
|
|
77
|
+
Vnořené asociace se zapisují pomocí '__' mezi názvy prostředků.
|
|
78
|
+
Například 'user,node' přeloží tyto dvě asociace.
|
|
79
|
+
Pro přeložení dalších asociací uzlu použijte např. 'user,node__location',
|
|
80
|
+
pro ještě hlubší úroveň např. 'user,node__location__environment'.
|
|
81
|
+
label: Zahrnuté asociace
|
|
82
|
+
path_params:
|
|
83
|
+
description: Pole parametrů potřebných k přeložení URL na tento objekt
|
|
84
|
+
label: Parametry URL
|
|
85
|
+
resolved:
|
|
86
|
+
description: True, pokud je asociace přeložena
|
|
87
|
+
label: Přeloženo
|
|
88
|
+
authentication:
|
|
89
|
+
token:
|
|
90
|
+
interval:
|
|
91
|
+
description: Jak dlouho bude požadovaný token platný, v sekundách.
|
|
92
|
+
label: Interval
|
|
93
|
+
lifetime:
|
|
94
|
+
description: |-
|
|
95
|
+
fixed - token má pevnou dobu platnosti a nelze ho obnovit
|
|
96
|
+
renewable_manual - token lze obnovit, ale musí se obnovit ručně akcí renew
|
|
97
|
+
renewable_auto - token se při každém použití automaticky obnoví na now+interval
|
|
98
|
+
permanent - token bude platný navždy, dokud nebude smazán
|
|
99
|
+
label: Životnost
|
|
100
|
+
password:
|
|
101
|
+
label: Heslo
|
|
102
|
+
scope:
|
|
103
|
+
label: Rozsah
|
|
104
|
+
user:
|
|
105
|
+
label: Uživatel
|
|
106
|
+
default:
|
|
107
|
+
count:
|
|
108
|
+
label: Vrátit počet všech položek
|
|
109
|
+
total_count:
|
|
110
|
+
label: Celkový počet všech položek
|
|
111
|
+
metadata:
|
|
112
|
+
'no':
|
|
113
|
+
label: Zakázat metadata
|
|
114
|
+
paginable:
|
|
115
|
+
from_id:
|
|
116
|
+
description: Vypsat objekty s větším/menším ID
|
|
117
|
+
label: Od ID
|
|
118
|
+
limit:
|
|
119
|
+
description: Počet objektů k načtení
|
|
120
|
+
label: Limit
|
|
121
|
+
types:
|
|
122
|
+
invalid_boolean: neplatná pravdivostní hodnota %{value}
|
|
123
|
+
invalid_datetime: není ve formátu ISO 8601 '%{value}'
|
|
124
|
+
invalid_float: neplatné desetinné číslo %{value}
|
|
125
|
+
invalid_integer: neplatné celé číslo %{value}
|
|
126
|
+
invalid_string: neplatný řetězec %{value}
|
|
127
|
+
validation:
|
|
128
|
+
cannot_be_null: nesmí být null
|
|
129
|
+
includes_only_strings: includes musí obsahovat jen řetězce
|
|
130
|
+
includes_string_or_array: includes musí být řetězec nebo pole
|
|
131
|
+
input_parameters_not_valid: vstupní parametry nejsou platné
|
|
132
|
+
invalid_id: neplatné ID %{value}
|
|
133
|
+
invalid_input_layout: neplatná struktura vstupu
|
|
134
|
+
invalid_path_parameter_encoding: neplatné kódování parametru cesty
|
|
135
|
+
invalid_string_encoding: neplatné kódování řetězce
|
|
136
|
+
required_parameter_missing: povinný parametr chybí
|
|
137
|
+
resource_not_found: prostředek nebyl nalezen
|
|
138
|
+
validators:
|
|
139
|
+
acceptance:
|
|
140
|
+
accepted: musí být %{value}
|
|
141
|
+
confirmation:
|
|
142
|
+
different: musí být odlišné od %{parameter}
|
|
143
|
+
same: musí být stejné jako %{parameter}
|
|
144
|
+
exclusion:
|
|
145
|
+
excluded: "%{value} nelze použít"
|
|
146
|
+
format:
|
|
147
|
+
invalid: "%{value} nemá platný formát"
|
|
148
|
+
inclusion:
|
|
149
|
+
included: "%{value} nelze použít"
|
|
150
|
+
length:
|
|
151
|
+
equals: délka musí být %{equals}
|
|
152
|
+
max: délka může být nejvýše %{max}
|
|
153
|
+
min: délka musí být alespoň %{min}
|
|
154
|
+
range: délka musí být v rozsahu <%{min}, %{max}>
|
|
155
|
+
numericality:
|
|
156
|
+
composite: "%{requirements}"
|
|
157
|
+
even: sudé číslo
|
|
158
|
+
max: musí být nejvýše %{max}
|
|
159
|
+
min: musí být alespoň %{min}
|
|
160
|
+
mod: zbytek po dělení %{mod} musí být nula
|
|
161
|
+
number: musí být číslo
|
|
162
|
+
odd: liché číslo
|
|
163
|
+
range: musí být v rozsahu <%{min}, %{max}>
|
|
164
|
+
step: v krocích po %{step}
|
|
165
|
+
presence:
|
|
166
|
+
non_empty: musí být vyplněno a neprázdné
|
|
167
|
+
present: musí být vyplněno
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# This file is generated from i18n/haveapi.yml.
|
|
2
|
+
# Do not edit it manually; manual changes will be overwritten.
|
|
3
|
+
# Update i18n/haveapi.yml and run bundle exec rake i18n:update.
|
|
4
|
+
---
|
|
5
|
+
en:
|
|
6
|
+
haveapi:
|
|
7
|
+
action_state:
|
|
8
|
+
cancellation_failed: cancellation failed
|
|
9
|
+
not_found: action state not found
|
|
10
|
+
timeout_max: timeout has to be maximally %{max}
|
|
11
|
+
authentication:
|
|
12
|
+
failed: authentication failed
|
|
13
|
+
invalid_credentials: invalid authentication credentials
|
|
14
|
+
multiple_oauth2_tokens: Multiple OAuth2 tokens provided
|
|
15
|
+
multiple_tokens: Multiple authentication tokens provided
|
|
16
|
+
renew_failed: renew failed
|
|
17
|
+
required: Action requires user to authenticate
|
|
18
|
+
revoke_failed: revoke failed
|
|
19
|
+
token_required: Action requires user to authenticate with a token
|
|
20
|
+
authorization:
|
|
21
|
+
insufficient_permissions: Access denied. Insufficient permissions.
|
|
22
|
+
errors:
|
|
23
|
+
action_not_found: Action not found
|
|
24
|
+
bad_accept_header: Bad Accept header
|
|
25
|
+
bad_json_syntax: Bad JSON syntax
|
|
26
|
+
json_body_object: JSON body must be an object
|
|
27
|
+
server_error: Server error occurred
|
|
28
|
+
unsupported_content_type: Unsupported Content-Type
|
|
29
|
+
pagination:
|
|
30
|
+
limit_max: limit has to be maximally %{max}
|
|
31
|
+
parameters:
|
|
32
|
+
action_state:
|
|
33
|
+
can_cancel:
|
|
34
|
+
description: When true, execution of this action can be cancelled
|
|
35
|
+
label: Can cancel
|
|
36
|
+
created_at:
|
|
37
|
+
label: Created at
|
|
38
|
+
current:
|
|
39
|
+
label: Current progress
|
|
40
|
+
finished:
|
|
41
|
+
label: Finished
|
|
42
|
+
label:
|
|
43
|
+
label: Label
|
|
44
|
+
poll:
|
|
45
|
+
current:
|
|
46
|
+
description: progress to check with if update_in is set
|
|
47
|
+
status:
|
|
48
|
+
description: status to check with if update_in is set
|
|
49
|
+
timeout:
|
|
50
|
+
description: in seconds
|
|
51
|
+
label: Timeout
|
|
52
|
+
total:
|
|
53
|
+
description: progress to check with if update_in is set
|
|
54
|
+
update_in:
|
|
55
|
+
description: number of seconds after which the state is returned if the
|
|
56
|
+
progress has changed
|
|
57
|
+
label: Progress
|
|
58
|
+
status:
|
|
59
|
+
description: Determines whether the action is proceeding or failing
|
|
60
|
+
label: Status
|
|
61
|
+
total:
|
|
62
|
+
description: The action is finished when current equals to total
|
|
63
|
+
label: Total
|
|
64
|
+
unit:
|
|
65
|
+
description: Unit of current and total
|
|
66
|
+
label: Unit
|
|
67
|
+
updated_at:
|
|
68
|
+
description: When was the progress last updated
|
|
69
|
+
label: Updated at
|
|
70
|
+
action_state_id:
|
|
71
|
+
description: ID of ActionState object for state querying. When null, the action
|
|
72
|
+
is not blocking for the current invocation.
|
|
73
|
+
label: Action state ID
|
|
74
|
+
active_record:
|
|
75
|
+
includes:
|
|
76
|
+
description: |-
|
|
77
|
+
A list of names of associated resources separated by a comma.
|
|
78
|
+
Nested associations are declared with '__' between resource names.
|
|
79
|
+
For example, 'user,node' will resolve the two associations.
|
|
80
|
+
To resolve further associations of node, use e.g. 'user,node__location',
|
|
81
|
+
to go even deeper, use e.g. 'user,node__location__environment'.
|
|
82
|
+
label: Included associations
|
|
83
|
+
path_params:
|
|
84
|
+
description: An array of parameters needed to resolve URL to this object
|
|
85
|
+
label: URL parameters
|
|
86
|
+
resolved:
|
|
87
|
+
description: True if the association is resolved
|
|
88
|
+
label: Resolved
|
|
89
|
+
authentication:
|
|
90
|
+
token:
|
|
91
|
+
interval:
|
|
92
|
+
description: How long will requested token be valid, in seconds.
|
|
93
|
+
label: Interval
|
|
94
|
+
lifetime:
|
|
95
|
+
description: |-
|
|
96
|
+
fixed - the token has a fixed validity period, it cannot be renewed
|
|
97
|
+
renewable_manual - the token can be renewed, but it must be done manually via renew action
|
|
98
|
+
renewable_auto - the token is renewed automatically to now+interval every time it is used
|
|
99
|
+
permanent - the token will be valid forever, unless deleted
|
|
100
|
+
label: Lifetime
|
|
101
|
+
password:
|
|
102
|
+
label: Password
|
|
103
|
+
scope:
|
|
104
|
+
label: Scope
|
|
105
|
+
user:
|
|
106
|
+
label: User
|
|
107
|
+
default:
|
|
108
|
+
count:
|
|
109
|
+
label: Return the count of all items
|
|
110
|
+
total_count:
|
|
111
|
+
label: Total count of all items
|
|
112
|
+
metadata:
|
|
113
|
+
'no':
|
|
114
|
+
label: Disable metadata
|
|
115
|
+
paginable:
|
|
116
|
+
from_id:
|
|
117
|
+
description: List objects with greater/lesser ID
|
|
118
|
+
label: From ID
|
|
119
|
+
limit:
|
|
120
|
+
description: Number of objects to retrieve
|
|
121
|
+
label: Limit
|
|
122
|
+
types:
|
|
123
|
+
invalid_boolean: not a valid boolean %{value}
|
|
124
|
+
invalid_datetime: not in ISO 8601 format '%{value}'
|
|
125
|
+
invalid_float: not a valid float %{value}
|
|
126
|
+
invalid_integer: not a valid integer %{value}
|
|
127
|
+
invalid_string: not a valid string %{value}
|
|
128
|
+
validation:
|
|
129
|
+
cannot_be_null: cannot be null
|
|
130
|
+
includes_only_strings: includes must contain only strings
|
|
131
|
+
includes_string_or_array: includes must be a string or array
|
|
132
|
+
input_parameters_not_valid: input parameters not valid
|
|
133
|
+
invalid_id: not a valid id %{value}
|
|
134
|
+
invalid_input_layout: invalid input layout
|
|
135
|
+
invalid_path_parameter_encoding: invalid path parameter encoding
|
|
136
|
+
invalid_string_encoding: invalid string encoding
|
|
137
|
+
required_parameter_missing: required parameter missing
|
|
138
|
+
resource_not_found: resource not found
|
|
139
|
+
validators:
|
|
140
|
+
acceptance:
|
|
141
|
+
accepted: has to be %{value}
|
|
142
|
+
confirmation:
|
|
143
|
+
different: must be different from %{parameter}
|
|
144
|
+
same: must be the same as %{parameter}
|
|
145
|
+
exclusion:
|
|
146
|
+
excluded: "%{value} cannot be used"
|
|
147
|
+
format:
|
|
148
|
+
invalid: "%{value} is not in a valid format"
|
|
149
|
+
inclusion:
|
|
150
|
+
included: "%{value} cannot be used"
|
|
151
|
+
length:
|
|
152
|
+
equals: length has to be %{equals}
|
|
153
|
+
max: length has to be maximally %{max}
|
|
154
|
+
min: length has to be minimally %{min}
|
|
155
|
+
range: length has to be in range <%{min}, %{max}>
|
|
156
|
+
numericality:
|
|
157
|
+
composite: "%{requirements}"
|
|
158
|
+
even: even
|
|
159
|
+
max: has to be maximally %{max}
|
|
160
|
+
min: has to be minimally %{min}
|
|
161
|
+
mod: mod %{mod} must equal zero
|
|
162
|
+
number: has to be a number
|
|
163
|
+
odd: odd
|
|
164
|
+
range: has to be in range <%{min}, %{max}>
|
|
165
|
+
step: in steps of %{step}
|
|
166
|
+
presence:
|
|
167
|
+
non_empty: must be present and non-empty
|
|
168
|
+
present: must be present
|
data/lib/haveapi/metadata.rb
CHANGED
|
@@ -45,12 +45,34 @@ module HaveAPI
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def describe(context)
|
|
48
|
+
def describe(context, type:)
|
|
49
49
|
{
|
|
50
|
-
input: @input && @input.describe(
|
|
51
|
-
|
|
50
|
+
input: @input && @input.describe(
|
|
51
|
+
context,
|
|
52
|
+
i18n_path: Params.metadata_i18n_path(context, type, :input)
|
|
53
|
+
),
|
|
54
|
+
output: @output && @output.describe(
|
|
55
|
+
context,
|
|
56
|
+
metadata: true,
|
|
57
|
+
i18n_path: Params.metadata_i18n_path(context, type, :output)
|
|
58
|
+
)
|
|
52
59
|
}
|
|
53
60
|
end
|
|
61
|
+
|
|
62
|
+
def parameter_metadata_i18n_items(context, type:)
|
|
63
|
+
[
|
|
64
|
+
*@input&.parameter_metadata_i18n_items(
|
|
65
|
+
context,
|
|
66
|
+
i18n_path: Params.metadata_i18n_path(context, type, :input),
|
|
67
|
+
meta_type: type
|
|
68
|
+
),
|
|
69
|
+
*@output&.parameter_metadata_i18n_items(
|
|
70
|
+
context,
|
|
71
|
+
i18n_path: Params.metadata_i18n_path(context, type, :output),
|
|
72
|
+
meta_type: type
|
|
73
|
+
)
|
|
74
|
+
].compact
|
|
75
|
+
end
|
|
54
76
|
end
|
|
55
77
|
end
|
|
56
78
|
end
|
|
@@ -81,7 +81,10 @@ module HaveAPI::ModelAdapters
|
|
|
81
81
|
|
|
82
82
|
if limit && limit > HaveAPI::Actions::Paginable::MAX_LIMIT
|
|
83
83
|
error!(
|
|
84
|
-
|
|
84
|
+
HaveAPI.message(
|
|
85
|
+
'haveapi.pagination.limit_max',
|
|
86
|
+
max: HaveAPI::Actions::Paginable::MAX_LIMIT
|
|
87
|
+
),
|
|
85
88
|
{},
|
|
86
89
|
http_status: 400
|
|
87
90
|
)
|
|
@@ -174,18 +177,18 @@ module HaveAPI::ModelAdapters
|
|
|
174
177
|
if raw.nil?
|
|
175
178
|
return nil if allow_null
|
|
176
179
|
|
|
177
|
-
raise
|
|
180
|
+
raise invalid_id(original)
|
|
178
181
|
end
|
|
179
182
|
|
|
180
183
|
if raw.is_a?(Array) || raw.is_a?(Hash) || [true, false].include?(raw)
|
|
181
|
-
raise
|
|
184
|
+
raise invalid_id(original)
|
|
182
185
|
elsif raw.is_a?(String)
|
|
183
186
|
stripped = raw.strip
|
|
184
187
|
|
|
185
188
|
if stripped.empty?
|
|
186
189
|
return nil if allow_null
|
|
187
190
|
|
|
188
|
-
raise
|
|
191
|
+
raise invalid_id(original)
|
|
189
192
|
end
|
|
190
193
|
|
|
191
194
|
raw = stripped
|
|
@@ -193,7 +196,7 @@ module HaveAPI::ModelAdapters
|
|
|
193
196
|
|
|
194
197
|
value = if integer_pk?(model)
|
|
195
198
|
id = coerce_integer_id(raw, original)
|
|
196
|
-
raise
|
|
199
|
+
raise invalid_id(original) if id < 0
|
|
197
200
|
|
|
198
201
|
id
|
|
199
202
|
else
|
|
@@ -207,14 +210,14 @@ module HaveAPI::ModelAdapters
|
|
|
207
210
|
end
|
|
208
211
|
|
|
209
212
|
if ret.nil? && !allow_null
|
|
210
|
-
raise
|
|
213
|
+
raise resource_not_found
|
|
211
214
|
end
|
|
212
215
|
|
|
213
216
|
ret
|
|
214
217
|
rescue ::ActiveRecord::RecordNotFound
|
|
215
|
-
raise
|
|
218
|
+
raise resource_not_found
|
|
216
219
|
rescue ArgumentError, TypeError
|
|
217
|
-
raise
|
|
220
|
+
raise invalid_id(original)
|
|
218
221
|
end
|
|
219
222
|
|
|
220
223
|
def self.integer_pk?(model)
|
|
@@ -232,7 +235,7 @@ module HaveAPI::ModelAdapters
|
|
|
232
235
|
raw
|
|
233
236
|
when Float
|
|
234
237
|
unless raw.finite? && (raw % 1) == 0
|
|
235
|
-
raise
|
|
238
|
+
raise invalid_id(original)
|
|
236
239
|
end
|
|
237
240
|
|
|
238
241
|
raw.to_i
|
|
@@ -240,23 +243,38 @@ module HaveAPI::ModelAdapters
|
|
|
240
243
|
s = raw.strip
|
|
241
244
|
|
|
242
245
|
if s.empty? || !s.match?(/\A[+-]?\d+\z/)
|
|
243
|
-
raise
|
|
246
|
+
raise invalid_id(original)
|
|
244
247
|
end
|
|
245
248
|
|
|
246
249
|
Integer(s, 10)
|
|
247
250
|
else
|
|
248
|
-
raise
|
|
251
|
+
raise invalid_id(original)
|
|
249
252
|
end
|
|
250
253
|
end
|
|
254
|
+
|
|
255
|
+
def self.invalid_id(original)
|
|
256
|
+
HaveAPI::ValidationError.new(
|
|
257
|
+
HaveAPI.message('haveapi.validation.invalid_id', value: original.inspect)
|
|
258
|
+
)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def self.resource_not_found
|
|
262
|
+
HaveAPI::ValidationError.new(
|
|
263
|
+
HaveAPI.message('haveapi.validation.resource_not_found')
|
|
264
|
+
)
|
|
265
|
+
end
|
|
251
266
|
end
|
|
252
267
|
|
|
253
268
|
class Output < ::HaveAPI::ModelAdapter::Output
|
|
254
269
|
def self.used_by(action)
|
|
255
270
|
action.meta(:object) do
|
|
256
271
|
output do
|
|
257
|
-
custom :path_params,
|
|
258
|
-
|
|
259
|
-
|
|
272
|
+
custom :path_params,
|
|
273
|
+
label: HaveAPI.message('haveapi.parameters.active_record.path_params.label'),
|
|
274
|
+
desc: HaveAPI.message('haveapi.parameters.active_record.path_params.description')
|
|
275
|
+
bool :resolved,
|
|
276
|
+
label: HaveAPI.message('haveapi.parameters.active_record.resolved.label'),
|
|
277
|
+
desc: HaveAPI.message('haveapi.parameters.active_record.resolved.description')
|
|
260
278
|
end
|
|
261
279
|
end
|
|
262
280
|
|
|
@@ -268,30 +286,26 @@ module HaveAPI::ModelAdapters
|
|
|
268
286
|
elsif raw.is_a?(Array)
|
|
269
287
|
raw
|
|
270
288
|
else
|
|
271
|
-
raise HaveAPI::ValidationError,
|
|
289
|
+
raise HaveAPI::ValidationError,
|
|
290
|
+
HaveAPI.message('haveapi.validation.includes_string_or_array')
|
|
272
291
|
end
|
|
273
292
|
|
|
274
293
|
values.map do |value|
|
|
275
294
|
unless value.is_a?(String)
|
|
276
|
-
raise HaveAPI::ValidationError,
|
|
295
|
+
raise HaveAPI::ValidationError,
|
|
296
|
+
HaveAPI.message('haveapi.validation.includes_only_strings')
|
|
277
297
|
end
|
|
278
298
|
|
|
279
299
|
value.strip
|
|
280
300
|
end
|
|
281
301
|
end
|
|
282
302
|
|
|
283
|
-
desc = <<~END
|
|
284
|
-
A list of names of associated resources separated by a comma.
|
|
285
|
-
Nested associations are declared with '__' between resource names.
|
|
286
|
-
For example, 'user,node' will resolve the two associations.
|
|
287
|
-
To resolve further associations of node, use e.g. 'user,node__location',
|
|
288
|
-
to go even deeper, use e.g. 'user,node__location__environment'.
|
|
289
|
-
END
|
|
290
|
-
|
|
291
303
|
action.meta(:global) do
|
|
292
304
|
input do
|
|
293
|
-
custom :includes,
|
|
294
|
-
|
|
305
|
+
custom :includes,
|
|
306
|
+
label: HaveAPI.message('haveapi.parameters.active_record.includes.label'),
|
|
307
|
+
desc: HaveAPI.message('haveapi.parameters.active_record.includes.description'),
|
|
308
|
+
&clean
|
|
295
309
|
end
|
|
296
310
|
end
|
|
297
311
|
|