servactory 3.1.0.rc1 → 3.1.0.rc3
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/LICENSE +21 -0
- data/README.md +2 -2
- data/config/locales/ja.yml +134 -0
- data/lib/generators/README.md +1 -1
- data/lib/servactory/configuration/config.rb +16 -0
- data/lib/servactory/configuration/configurable.rb +6 -3
- data/lib/servactory/configuration/hash_mode/class_names_collection.rb +4 -1
- data/lib/servactory/configuration/option_helpers/option_helpers_collection.rb +14 -0
- data/lib/servactory/context/warehouse/inputs.rb +15 -28
- data/lib/servactory/context/workspace/inputs.rb +20 -17
- data/lib/servactory/context/workspace/internals.rb +36 -31
- data/lib/servactory/context/workspace/outputs.rb +28 -30
- data/lib/servactory/inputs/tools/validation.rb +10 -18
- data/lib/servactory/maintenance/options/collection.rb +26 -16
- data/lib/servactory/maintenance/options/registrar.rb +1 -1
- data/lib/servactory/maintenance/validations/performer.rb +12 -23
- data/lib/servactory/result.rb +25 -40
- data/lib/servactory/test_kit/rspec/helpers/mock_executor.rb +6 -2
- data/lib/servactory/test_kit/rspec/helpers/service_mock_builder.rb +78 -8
- data/lib/servactory/test_kit/rspec/helpers/service_mock_config.rb +19 -2
- data/lib/servactory/tool_kit/dynamic_options/consists_of.rb +5 -3
- data/lib/servactory/tool_kit/dynamic_options/format.rb +1 -1
- data/lib/servactory/tool_kit/dynamic_options/inclusion.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/max.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/min.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/multiple_of.rb +2 -2
- data/lib/servactory/tool_kit/dynamic_options/schema.rb +6 -4
- data/lib/servactory/tool_kit/dynamic_options/target.rb +3 -3
- data/lib/servactory/version.rb +1 -1
- data/lib/servactory.rb +0 -4
- metadata +12 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5acfb374e0e85d7779b99658fcb899007ca346ca63c71344800490428ac61dd
|
|
4
|
+
data.tar.gz: 94ff484e768908909aa856d63310af3c896f198357b88c3089fe9393de53bc88
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61facdd48b89752c3f2bfe0735c87c24f83c225c2474608c9aa871f150003a996b2b4775ef25941f0916f45524383cdf1e1814a237b522add763782c2ec03e9b
|
|
7
|
+
data.tar.gz: 13202fe9276b8323cd83fc2c0919613eeabfd9d99b4d1cfac541ef7ed88739a84c6d5719a44ca76fe960c33aaf6a66b1b9c9353e12a1e5662b8e19df05a68fd3
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Anton Sokolov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -52,7 +52,7 @@ gem "servactory"
|
|
|
52
52
|
### Define service
|
|
53
53
|
|
|
54
54
|
```ruby
|
|
55
|
-
class
|
|
55
|
+
class Users::Authenticate < Servactory::Base
|
|
56
56
|
input :email, type: String
|
|
57
57
|
input :password, type: String
|
|
58
58
|
|
|
@@ -77,7 +77,7 @@ end
|
|
|
77
77
|
```ruby
|
|
78
78
|
class SessionsController < ApplicationController
|
|
79
79
|
def create
|
|
80
|
-
service =
|
|
80
|
+
service = Users::Authenticate.call(**session_params)
|
|
81
81
|
|
|
82
82
|
if service.success?
|
|
83
83
|
session[:current_user_id] = service.user.id
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
ja:
|
|
2
|
+
servactory:
|
|
3
|
+
common:
|
|
4
|
+
undefined_method:
|
|
5
|
+
missing_name: "[%{service_class_name}] %{error_text}"
|
|
6
|
+
methods:
|
|
7
|
+
call:
|
|
8
|
+
not_used: "[%{service_class_name}] 実行する処理がありません。`make`を使用するか、`call`メソッドを作成してください。"
|
|
9
|
+
cannot_be_overwritten: "[%{service_class_name}] 次のメソッドは上書きできません: %{list_of_methods}"
|
|
10
|
+
inputs:
|
|
11
|
+
undefined:
|
|
12
|
+
for_fetch: "[%{service_class_name}] 未定義の入力`%{input_name}`"
|
|
13
|
+
for_assign: "[%{service_class_name}] 未定義の入力`%{input_name}`"
|
|
14
|
+
validations:
|
|
15
|
+
must:
|
|
16
|
+
default_error: "[%{service_class_name}] 入力`%{input_name}`は「%{code}」を満たす必要があります"
|
|
17
|
+
syntax_error: "[%{service_class_name}] 入力`%{input_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
18
|
+
dynamic_options:
|
|
19
|
+
consists_of:
|
|
20
|
+
required: "[%{service_class_name}] 入力コレクション`%{input_name}`の必須要素が不足しています"
|
|
21
|
+
wrong_type: "[%{service_class_name}] 入力コレクション`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
22
|
+
wrong_element_type: "[%{service_class_name}] 入力コレクション`%{input_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
23
|
+
format:
|
|
24
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマットに一致しません"
|
|
25
|
+
wrong_pattern: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマットに一致しません"
|
|
26
|
+
wrong_type: "[%{service_class_name}] 入力`%{input_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
27
|
+
unknown: "[%{service_class_name}] 入力`%{input_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
28
|
+
inclusion:
|
|
29
|
+
default: "[%{service_class_name}] `%{input_name}`の値が不正です。`%{input_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
30
|
+
invalid_option: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに値がありません"
|
|
31
|
+
min:
|
|
32
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
33
|
+
max:
|
|
34
|
+
default: "[%{service_class_name}] 入力`%{input_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
35
|
+
multiple_of:
|
|
36
|
+
default: "[%{service_class_name}] 入力`%{input_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
37
|
+
blank: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
38
|
+
divided_by_0: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
39
|
+
schema:
|
|
40
|
+
wrong_type: "[%{service_class_name}] 入力`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
41
|
+
wrong_element_type: "[%{service_class_name}] 入力ハッシュ`%{input_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
42
|
+
wrong_element_value: "[%{service_class_name}] 入力ハッシュ`%{input_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
43
|
+
target:
|
|
44
|
+
default: "[%{service_class_name}] 入力`%{input_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
45
|
+
invalid_option: "[%{service_class_name}] 入力`%{input_name}`の`%{option_name}`オプションに値がありません"
|
|
46
|
+
required:
|
|
47
|
+
default_error:
|
|
48
|
+
default: "[%{service_class_name}] 必須の入力`%{input_name}`が不足しています"
|
|
49
|
+
type:
|
|
50
|
+
default_error:
|
|
51
|
+
default: "[%{service_class_name}] 入力`%{input_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
52
|
+
tools:
|
|
53
|
+
find_unnecessary:
|
|
54
|
+
error: "[%{service_class_name}] 予期しない属性: `%{unnecessary_attributes}`"
|
|
55
|
+
rules:
|
|
56
|
+
error: "[%{service_class_name}] 入力`%{input_name}`のオプションに競合があります: `%{conflict_code}`"
|
|
57
|
+
internals:
|
|
58
|
+
undefined:
|
|
59
|
+
for_fetch: "[%{service_class_name}] 未定義の内部属性`%{internal_name}`"
|
|
60
|
+
for_assign: "[%{service_class_name}] 未定義の内部属性`%{internal_name}`"
|
|
61
|
+
validations:
|
|
62
|
+
must:
|
|
63
|
+
default_error: "[%{service_class_name}] 内部属性`%{internal_name}`は「%{code}」を満たす必要があります"
|
|
64
|
+
syntax_error: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
65
|
+
dynamic_options:
|
|
66
|
+
consists_of:
|
|
67
|
+
required: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の必須要素が不足しています"
|
|
68
|
+
wrong_type: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
69
|
+
wrong_element_type: "[%{service_class_name}] 内部属性コレクション`%{internal_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
70
|
+
format:
|
|
71
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマットに一致しません"
|
|
72
|
+
wrong_pattern: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマットに一致しません"
|
|
73
|
+
wrong_type: "[%{service_class_name}] 内部属性`%{internal_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
74
|
+
unknown: "[%{service_class_name}] 内部属性`%{internal_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
75
|
+
inclusion:
|
|
76
|
+
default: "[%{service_class_name}] `%{internal_name}`の値が不正です。`%{internal_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
77
|
+
invalid_option: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに値がありません"
|
|
78
|
+
min:
|
|
79
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
80
|
+
max:
|
|
81
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
82
|
+
multiple_of:
|
|
83
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
84
|
+
blank: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
85
|
+
divided_by_0: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
86
|
+
schema:
|
|
87
|
+
wrong_type: "[%{service_class_name}] 内部属性`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
88
|
+
wrong_element_type: "[%{service_class_name}] 内部属性ハッシュ`%{internal_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
89
|
+
wrong_element_value: "[%{service_class_name}] 内部属性ハッシュ`%{internal_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
90
|
+
target:
|
|
91
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
92
|
+
invalid_option: "[%{service_class_name}] 内部属性`%{internal_name}`の`%{option_name}`オプションに値がありません"
|
|
93
|
+
type:
|
|
94
|
+
default_error:
|
|
95
|
+
default: "[%{service_class_name}] 内部属性`%{internal_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
96
|
+
outputs:
|
|
97
|
+
undefined:
|
|
98
|
+
for_fetch: "[%{service_class_name}] 未定義の出力属性`%{output_name}`"
|
|
99
|
+
for_assign: "[%{service_class_name}] 未定義の出力属性`%{output_name}`"
|
|
100
|
+
validations:
|
|
101
|
+
must:
|
|
102
|
+
default_error: "[%{service_class_name}] 出力属性`%{output_name}`は「%{code}」を満たす必要があります"
|
|
103
|
+
syntax_error: "[%{service_class_name}] 出力属性`%{output_name}`の`%{code}`内の構文エラー: %{exception_message}"
|
|
104
|
+
dynamic_options:
|
|
105
|
+
consists_of:
|
|
106
|
+
required: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の必須要素が不足しています"
|
|
107
|
+
wrong_type: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
108
|
+
wrong_element_type: "[%{service_class_name}] 出力属性コレクション`%{output_name}`の要素の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
109
|
+
format:
|
|
110
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマットに一致しません"
|
|
111
|
+
wrong_pattern: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマットに一致しません"
|
|
112
|
+
wrong_type: "[%{service_class_name}] 出力属性`%{output_name}`は`%{format_name}`フォーマット検証のためにStringである必要があります"
|
|
113
|
+
unknown: "[%{service_class_name}] 出力属性`%{output_name}`に指定された`%{format_name}`フォーマットは不明です"
|
|
114
|
+
inclusion:
|
|
115
|
+
default: "[%{service_class_name}] `%{output_name}`の値が不正です。`%{output_inclusion}`のいずれかである必要がありますが、`%{value}`が渡されました"
|
|
116
|
+
invalid_option: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに値がありません"
|
|
117
|
+
min:
|
|
118
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より小さいです"
|
|
119
|
+
max:
|
|
120
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`は値`%{value}`を受け取りましたが、`%{option_value}`より大きいです"
|
|
121
|
+
multiple_of:
|
|
122
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`の値`%{value}`は`%{option_value}`の倍数ではありません"
|
|
123
|
+
blank: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
124
|
+
divided_by_0: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに無効な値`%{option_value}`があります"
|
|
125
|
+
schema:
|
|
126
|
+
wrong_type: "[%{service_class_name}] 出力属性`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
127
|
+
wrong_element_type: "[%{service_class_name}] 出力属性ハッシュ`%{output_name}`の型が不正です。`%{key_name}`には`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
|
128
|
+
wrong_element_value: "[%{service_class_name}] 出力属性ハッシュ`%{output_name}`の値が不正です。`%{key_name}`には`%{expected_type}`型の値が期待されましたが、`%{given_type}`が渡されました"
|
|
129
|
+
target:
|
|
130
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`のターゲットが不正です。`%{expected_target}`である必要がありますが、`%{value}`が渡されました"
|
|
131
|
+
invalid_option: "[%{service_class_name}] 出力属性`%{output_name}`の`%{option_name}`オプションに値がありません"
|
|
132
|
+
type:
|
|
133
|
+
default_error:
|
|
134
|
+
default: "[%{service_class_name}] 出力属性`%{output_name}`の型が不正です。`%{expected_type}`が期待されましたが、`%{given_type}`が渡されました"
|
data/lib/generators/README.md
CHANGED
|
@@ -9,7 +9,7 @@ rails generate servactory:install [options]
|
|
|
9
9
|
**Options:**
|
|
10
10
|
- `--namespace` — Base namespace (default: `ApplicationService`)
|
|
11
11
|
- `--path` — Path to install service files (default: `app/services`)
|
|
12
|
-
- `--locales` — Locales to install (available: `en`, `ru`, `de`, `fr`, `es`, `it`)
|
|
12
|
+
- `--locales` — Locales to install (available: `en`, `ru`, `de`, `fr`, `es`, `it`, `ja`)
|
|
13
13
|
- `--minimal` — Generate minimal setup without configuration examples
|
|
14
14
|
|
|
15
15
|
## Service
|
|
@@ -30,6 +30,22 @@ module Servactory
|
|
|
30
30
|
@collection_mode_class_names = original.collection_mode_class_names.dup
|
|
31
31
|
@hash_mode_class_names = original.hash_mode_class_names.dup
|
|
32
32
|
@action_rescue_handlers = original.action_rescue_handlers.dup
|
|
33
|
+
|
|
34
|
+
rebind_dynamic_option_helpers!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def rebind_dynamic_option_helpers!
|
|
40
|
+
new_consists_of = Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
41
|
+
.use(collection_mode_class_names: @collection_mode_class_names)
|
|
42
|
+
new_schema = Servactory::ToolKit::DynamicOptions::Schema
|
|
43
|
+
.use(default_hash_mode_class_names: @hash_mode_class_names)
|
|
44
|
+
|
|
45
|
+
[@input_option_helpers, @internal_option_helpers, @output_option_helpers].each do |helpers|
|
|
46
|
+
helpers.replace(name: :consists_of, with: new_consists_of)
|
|
47
|
+
helpers.replace(name: :schema, with: new_schema)
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
end
|
|
@@ -67,7 +67,8 @@ module Servactory
|
|
|
67
67
|
.new(name: :optional, equivalent: { required: false }),
|
|
68
68
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
69
69
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
70
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
70
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
71
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
71
72
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
72
73
|
]
|
|
73
74
|
end
|
|
@@ -76,7 +77,8 @@ module Servactory
|
|
|
76
77
|
Set[
|
|
77
78
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
78
79
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
79
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
80
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
81
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
80
82
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
81
83
|
]
|
|
82
84
|
end
|
|
@@ -85,7 +87,8 @@ module Servactory
|
|
|
85
87
|
Set[
|
|
86
88
|
Servactory::ToolKit::DynamicOptions::ConsistsOf
|
|
87
89
|
.use(collection_mode_class_names: config.collection_mode_class_names),
|
|
88
|
-
Servactory::ToolKit::DynamicOptions::Schema
|
|
90
|
+
Servactory::ToolKit::DynamicOptions::Schema
|
|
91
|
+
.use(default_hash_mode_class_names: config.hash_mode_class_names),
|
|
89
92
|
Servactory::ToolKit::DynamicOptions::Inclusion.use
|
|
90
93
|
]
|
|
91
94
|
end
|
|
@@ -72,6 +72,20 @@ module Servactory
|
|
|
72
72
|
helpers_index[name]
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
+
# Replaces a helper by name with a new one, invalidating the index cache.
|
|
76
|
+
#
|
|
77
|
+
# @param name [Symbol] the helper name to replace
|
|
78
|
+
# @param with [Maintenance::Attributes::OptionHelper] the replacement helper
|
|
79
|
+
# @return [void]
|
|
80
|
+
def replace(name:, with:)
|
|
81
|
+
old = find_by(name:)
|
|
82
|
+
return unless old
|
|
83
|
+
|
|
84
|
+
@collection.delete(old)
|
|
85
|
+
@collection.add(with)
|
|
86
|
+
@helpers_index = nil
|
|
87
|
+
end
|
|
88
|
+
|
|
75
89
|
private
|
|
76
90
|
|
|
77
91
|
# Builds and caches a hash index for O(1) helper lookups.
|
|
@@ -29,55 +29,42 @@ module Servactory
|
|
|
29
29
|
@arguments.keys
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
# Merges new arguments into storage
|
|
32
|
+
# Merges new arguments into storage.
|
|
33
33
|
#
|
|
34
34
|
# @param arguments [Hash] Input name-value pairs to merge
|
|
35
|
-
# @return [
|
|
35
|
+
# @return [Hash] Updated arguments hash
|
|
36
36
|
def merge!(arguments)
|
|
37
37
|
@arguments.merge!(arguments)
|
|
38
|
-
define_methods_for!(arguments)
|
|
39
38
|
end
|
|
40
39
|
|
|
41
|
-
#
|
|
40
|
+
# Delegates method calls to stored inputs.
|
|
42
41
|
#
|
|
43
42
|
# Supports predicate methods when enabled in config.
|
|
44
43
|
#
|
|
45
44
|
# @param name [Symbol] Method name (input or predicate)
|
|
46
45
|
# @param _args [Array] Method arguments (unused)
|
|
47
|
-
# @
|
|
46
|
+
# @return [Object] Input value or predicate result
|
|
48
47
|
def method_missing(name, *_args)
|
|
49
48
|
predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
|
|
49
|
+
|
|
50
50
|
input_name = predicate ? name.to_s.chomp("?").to_sym : name
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
input_value = @arguments.fetch(input_name) { raise_error_for(input_name) }
|
|
53
|
+
|
|
54
|
+
predicate ? Servactory::Utils.query_attribute(input_value) : input_value
|
|
52
55
|
end
|
|
53
56
|
|
|
54
|
-
#
|
|
57
|
+
# Checks if method corresponds to stored input.
|
|
55
58
|
#
|
|
56
|
-
# @
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
# @param name [Symbol] Method name to check
|
|
60
|
+
# @return [Boolean] True if input exists for this method
|
|
61
|
+
def respond_to_missing?(name, *)
|
|
62
|
+
input_name = name.to_s.chomp("?").to_sym
|
|
63
|
+
@arguments.key?(input_name) || @arguments.key?(name) || super
|
|
59
64
|
end
|
|
60
65
|
|
|
61
66
|
private
|
|
62
67
|
|
|
63
|
-
# Defines singleton accessor methods for given arguments.
|
|
64
|
-
#
|
|
65
|
-
# @param arguments [Hash] Input name-value pairs to define methods for
|
|
66
|
-
# @return [void]
|
|
67
|
-
def define_methods_for!(arguments)
|
|
68
|
-
arguments.each_key do |name|
|
|
69
|
-
define_singleton_method(name) do
|
|
70
|
-
@arguments.fetch(name) { raise_error_for(name) }
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
next unless @context.config.predicate_methods_enabled
|
|
74
|
-
|
|
75
|
-
define_singleton_method(:"#{name}?") do
|
|
76
|
-
Servactory::Utils.query_attribute(@arguments.fetch(name) { raise_error_for(name) })
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
68
|
# Raises error for undefined input.
|
|
82
69
|
#
|
|
83
70
|
# @param input_name [Symbol] Name of undefined input
|
|
@@ -7,8 +7,6 @@ module Servactory
|
|
|
7
7
|
def initialize(context:, collection_of_inputs:)
|
|
8
8
|
@context = context
|
|
9
9
|
@collection_of_inputs = collection_of_inputs
|
|
10
|
-
|
|
11
|
-
define_attribute_methods!
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
def only(*names)
|
|
@@ -26,30 +24,31 @@ module Servactory
|
|
|
26
24
|
def method_missing(name, *_args)
|
|
27
25
|
if name.to_s.end_with?("=")
|
|
28
26
|
prepared_name = name.to_s.delete("=").to_sym
|
|
27
|
+
|
|
29
28
|
raise_error_for(:assign, prepared_name)
|
|
30
29
|
else
|
|
31
|
-
raise_error_for(:fetch, name)
|
|
30
|
+
fetch_with(name:) { raise_error_for(:fetch, name) }
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
def respond_to_missing?(*)
|
|
36
|
-
|
|
34
|
+
def respond_to_missing?(name, *)
|
|
35
|
+
resolve_input(name) || super
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
private
|
|
40
39
|
|
|
41
|
-
def
|
|
42
|
-
@
|
|
43
|
-
define_singleton_method(input.internal_name) do
|
|
44
|
-
fetch_value(attribute: input)
|
|
45
|
-
end
|
|
40
|
+
def fetch_with(name:, &_block)
|
|
41
|
+
predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
input_name = predicate ? name.to_s.chomp("?").to_sym : name
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
input = @collection_of_inputs.find_by(name: input_name)
|
|
46
|
+
|
|
47
|
+
return yield if input.nil?
|
|
48
|
+
|
|
49
|
+
value = fetch_value(attribute: input)
|
|
50
|
+
|
|
51
|
+
predicate ? Servactory::Utils.query_attribute(value) : value
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def fetch_value(attribute:)
|
|
@@ -65,8 +64,12 @@ module Servactory
|
|
|
65
64
|
value
|
|
66
65
|
end
|
|
67
66
|
|
|
68
|
-
def
|
|
69
|
-
|
|
67
|
+
def resolve_input(name)
|
|
68
|
+
return true if @collection_of_inputs.find_by(name:)
|
|
69
|
+
|
|
70
|
+
@context.config.predicate_methods_enabled &&
|
|
71
|
+
name.to_s.end_with?("?") &&
|
|
72
|
+
@collection_of_inputs.find_by(name: name.to_s.chomp("?").to_sym)
|
|
70
73
|
end
|
|
71
74
|
|
|
72
75
|
def raise_error_for(type, name)
|
|
@@ -7,9 +7,6 @@ module Servactory
|
|
|
7
7
|
def initialize(context:, collection_of_internals:)
|
|
8
8
|
@context = context
|
|
9
9
|
@collection_of_internals = collection_of_internals
|
|
10
|
-
@validated_attributes = Set.new
|
|
11
|
-
|
|
12
|
-
define_attribute_methods!
|
|
13
10
|
end
|
|
14
11
|
|
|
15
12
|
def only(*names)
|
|
@@ -24,57 +21,61 @@ module Servactory
|
|
|
24
21
|
.to_h { |internal| [internal.name, send(internal.name)] }
|
|
25
22
|
end
|
|
26
23
|
|
|
27
|
-
def method_missing(name, *
|
|
24
|
+
def method_missing(name, *args)
|
|
28
25
|
if name.to_s.end_with?("=")
|
|
29
26
|
prepared_name = name.to_s.delete("=").to_sym
|
|
30
|
-
|
|
27
|
+
|
|
28
|
+
assign_with(prepared_name:, value: args.pop) { raise_error_for(:assign, prepared_name) }
|
|
31
29
|
else
|
|
32
|
-
raise_error_for(:fetch, name)
|
|
30
|
+
fetch_with(name:) { raise_error_for(:fetch, name) }
|
|
33
31
|
end
|
|
34
32
|
end
|
|
35
33
|
|
|
36
|
-
def respond_to_missing?(*)
|
|
37
|
-
|
|
34
|
+
def respond_to_missing?(name, *)
|
|
35
|
+
resolve_internal(name) || super
|
|
38
36
|
end
|
|
39
37
|
|
|
40
38
|
private
|
|
41
39
|
|
|
42
|
-
def
|
|
43
|
-
@
|
|
44
|
-
|
|
45
|
-
fetch_value(attribute: internal)
|
|
46
|
-
end
|
|
40
|
+
def validated_attributes
|
|
41
|
+
@validated_attributes ||= Set.new
|
|
42
|
+
end
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
44
|
+
def assign_with(prepared_name:, value:, &_block)
|
|
45
|
+
internal = @collection_of_internals.find_by(name: prepared_name)
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
return yield if internal.nil?
|
|
53
48
|
|
|
54
|
-
|
|
55
|
-
fetch_predicate(attribute: internal)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def assign_value(attribute:, value:)
|
|
61
|
-
@validated_attributes.delete(attribute.name)
|
|
49
|
+
validated_attributes.delete(internal.name)
|
|
62
50
|
|
|
63
51
|
Servactory::Maintenance::Validations::Performer.validate!(
|
|
64
52
|
context: @context,
|
|
65
|
-
attribute
|
|
53
|
+
attribute: internal,
|
|
66
54
|
value:
|
|
67
55
|
)
|
|
68
56
|
|
|
69
|
-
@context.send(:servactory_service_warehouse).assign_internal(
|
|
57
|
+
@context.send(:servactory_service_warehouse).assign_internal(internal.name, value)
|
|
70
58
|
|
|
71
|
-
|
|
59
|
+
validated_attributes << internal.name
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def fetch_with(name:, &_block)
|
|
63
|
+
predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
|
|
64
|
+
|
|
65
|
+
internal_name = predicate ? name.to_s.chomp("?").to_sym : name
|
|
66
|
+
internal = @collection_of_internals.find_by(name: internal_name)
|
|
67
|
+
|
|
68
|
+
return yield if internal.nil?
|
|
69
|
+
|
|
70
|
+
internal_value = fetch_value(attribute: internal)
|
|
71
|
+
|
|
72
|
+
predicate ? Servactory::Utils.query_attribute(internal_value) : internal_value
|
|
72
73
|
end
|
|
73
74
|
|
|
74
75
|
def fetch_value(attribute:)
|
|
75
76
|
value = @context.send(:servactory_service_warehouse).fetch_internal(attribute.name)
|
|
76
77
|
|
|
77
|
-
if
|
|
78
|
+
if validated_attributes.exclude?(attribute.name)
|
|
78
79
|
Servactory::Maintenance::Validations::Performer.validate!(
|
|
79
80
|
context: @context,
|
|
80
81
|
attribute:,
|
|
@@ -85,8 +86,12 @@ module Servactory
|
|
|
85
86
|
value
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
def
|
|
89
|
-
|
|
89
|
+
def resolve_internal(name)
|
|
90
|
+
return true if @collection_of_internals.find_by(name:)
|
|
91
|
+
|
|
92
|
+
@context.config.predicate_methods_enabled &&
|
|
93
|
+
name.to_s.end_with?("?") &&
|
|
94
|
+
@collection_of_internals.find_by(name: name.to_s.chomp("?").to_sym)
|
|
90
95
|
end
|
|
91
96
|
|
|
92
97
|
def raise_error_for(type, name)
|
|
@@ -7,8 +7,6 @@ module Servactory
|
|
|
7
7
|
def initialize(context:, collection_of_outputs:)
|
|
8
8
|
@context = context
|
|
9
9
|
@collection_of_outputs = collection_of_outputs
|
|
10
|
-
|
|
11
|
-
define_attribute_methods!
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
def only(*names)
|
|
@@ -23,55 +21,55 @@ module Servactory
|
|
|
23
21
|
.to_h { |output| [output.name, send(output.name)] }
|
|
24
22
|
end
|
|
25
23
|
|
|
26
|
-
def method_missing(name, *
|
|
24
|
+
def method_missing(name, *args)
|
|
27
25
|
if name.to_s.end_with?("=")
|
|
28
26
|
prepared_name = name.to_s.delete("=").to_sym
|
|
29
|
-
|
|
27
|
+
|
|
28
|
+
assign_with(prepared_name:, value: args.pop) { raise_error_for(:assign, prepared_name) }
|
|
30
29
|
else
|
|
31
|
-
raise_error_for(:fetch, name)
|
|
30
|
+
fetch_with(name:) { raise_error_for(:fetch, name) }
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
def respond_to_missing?(*)
|
|
36
|
-
|
|
34
|
+
def respond_to_missing?(name, *)
|
|
35
|
+
resolve_output(name) || super
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
private
|
|
40
39
|
|
|
41
|
-
def
|
|
42
|
-
@collection_of_outputs.
|
|
43
|
-
define_singleton_method(output.name) do
|
|
44
|
-
fetch_value(attribute: output)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
define_singleton_method(:"#{output.name}=") do |value|
|
|
48
|
-
assign_value(attribute: output, value:)
|
|
49
|
-
end
|
|
40
|
+
def assign_with(prepared_name:, value:, &_block)
|
|
41
|
+
output = @collection_of_outputs.find_by(name: prepared_name)
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
define_singleton_method(:"#{output.name}?") do
|
|
54
|
-
fetch_predicate(attribute: output)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
43
|
+
return yield if output.nil?
|
|
58
44
|
|
|
59
|
-
def assign_value(attribute:, value:)
|
|
60
45
|
Servactory::Maintenance::Validations::Performer.validate!(
|
|
61
46
|
context: @context,
|
|
62
|
-
attribute
|
|
47
|
+
attribute: output,
|
|
63
48
|
value:
|
|
64
49
|
)
|
|
65
50
|
|
|
66
|
-
@context.send(:servactory_service_warehouse).assign_output(
|
|
51
|
+
@context.send(:servactory_service_warehouse).assign_output(output.name, value)
|
|
67
52
|
end
|
|
68
53
|
|
|
69
|
-
def
|
|
70
|
-
@context.
|
|
54
|
+
def fetch_with(name:, &_block)
|
|
55
|
+
predicate = @context.config.predicate_methods_enabled && name.end_with?("?")
|
|
56
|
+
|
|
57
|
+
output_name = predicate ? name.to_s.chomp("?").to_sym : name
|
|
58
|
+
output = @collection_of_outputs.find_by(name: output_name)
|
|
59
|
+
|
|
60
|
+
return yield if output.nil?
|
|
61
|
+
|
|
62
|
+
output_value = @context.send(:servactory_service_warehouse).fetch_output(output.name)
|
|
63
|
+
|
|
64
|
+
predicate ? Servactory::Utils.query_attribute(output_value) : output_value
|
|
71
65
|
end
|
|
72
66
|
|
|
73
|
-
def
|
|
74
|
-
|
|
67
|
+
def resolve_output(name)
|
|
68
|
+
return true if @collection_of_outputs.find_by(name:)
|
|
69
|
+
|
|
70
|
+
@context.config.predicate_methods_enabled &&
|
|
71
|
+
name.to_s.end_with?("?") &&
|
|
72
|
+
@collection_of_outputs.find_by(name: name.to_s.chomp("?").to_sym)
|
|
75
73
|
end
|
|
76
74
|
|
|
77
75
|
def raise_error_for(type, name)
|