cmdx 1.0.1 → 1.1.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/.cursor/prompts/rspec.md +20 -0
- data/.cursor/prompts/yardoc.md +8 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +17 -2
- data/README.md +1 -1
- data/docs/basics/call.md +2 -2
- data/docs/basics/chain.md +1 -1
- data/docs/callbacks.md +3 -36
- data/docs/configuration.md +58 -12
- data/docs/interruptions/exceptions.md +1 -1
- data/docs/interruptions/faults.md +2 -2
- data/docs/logging.md +4 -4
- data/docs/middlewares.md +43 -43
- data/docs/parameters/coercions.md +49 -38
- data/docs/parameters/defaults.md +1 -1
- data/docs/parameters/validations.md +0 -39
- data/docs/testing.md +11 -12
- data/docs/workflows.md +4 -4
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/callback.rb +36 -56
- data/lib/cmdx/callback_registry.rb +82 -73
- data/lib/cmdx/chain.rb +65 -122
- data/lib/cmdx/chain_inspector.rb +22 -115
- data/lib/cmdx/chain_serializer.rb +17 -148
- data/lib/cmdx/coercion.rb +49 -0
- data/lib/cmdx/coercion_registry.rb +94 -0
- data/lib/cmdx/coercions/array.rb +18 -36
- data/lib/cmdx/coercions/big_decimal.rb +21 -33
- data/lib/cmdx/coercions/boolean.rb +21 -40
- data/lib/cmdx/coercions/complex.rb +18 -31
- data/lib/cmdx/coercions/date.rb +20 -39
- data/lib/cmdx/coercions/date_time.rb +22 -39
- data/lib/cmdx/coercions/float.rb +19 -32
- data/lib/cmdx/coercions/hash.rb +22 -41
- data/lib/cmdx/coercions/integer.rb +20 -33
- data/lib/cmdx/coercions/rational.rb +20 -32
- data/lib/cmdx/coercions/string.rb +23 -31
- data/lib/cmdx/coercions/time.rb +24 -40
- data/lib/cmdx/coercions/virtual.rb +14 -31
- data/lib/cmdx/configuration.rb +57 -171
- data/lib/cmdx/context.rb +22 -165
- data/lib/cmdx/core_ext/hash.rb +42 -67
- data/lib/cmdx/core_ext/module.rb +35 -79
- data/lib/cmdx/core_ext/object.rb +63 -98
- data/lib/cmdx/correlator.rb +40 -156
- data/lib/cmdx/error.rb +37 -202
- data/lib/cmdx/errors.rb +165 -202
- data/lib/cmdx/fault.rb +55 -158
- data/lib/cmdx/faults.rb +26 -137
- data/lib/cmdx/immutator.rb +22 -109
- data/lib/cmdx/lazy_struct.rb +103 -187
- data/lib/cmdx/log_formatters/json.rb +14 -40
- data/lib/cmdx/log_formatters/key_value.rb +14 -40
- data/lib/cmdx/log_formatters/line.rb +14 -48
- data/lib/cmdx/log_formatters/logstash.rb +14 -57
- data/lib/cmdx/log_formatters/pretty_json.rb +14 -50
- data/lib/cmdx/log_formatters/pretty_key_value.rb +13 -46
- data/lib/cmdx/log_formatters/pretty_line.rb +16 -54
- data/lib/cmdx/log_formatters/raw.rb +19 -49
- data/lib/cmdx/logger.rb +20 -82
- data/lib/cmdx/logger_ansi.rb +18 -75
- data/lib/cmdx/logger_serializer.rb +24 -114
- data/lib/cmdx/middleware.rb +38 -60
- data/lib/cmdx/middleware_registry.rb +81 -77
- data/lib/cmdx/middlewares/correlate.rb +41 -226
- data/lib/cmdx/middlewares/timeout.rb +46 -185
- data/lib/cmdx/parameter.rb +120 -198
- data/lib/cmdx/parameter_evaluator.rb +231 -0
- data/lib/cmdx/parameter_inspector.rb +25 -56
- data/lib/cmdx/parameter_registry.rb +59 -84
- data/lib/cmdx/parameter_serializer.rb +23 -74
- data/lib/cmdx/railtie.rb +24 -107
- data/lib/cmdx/result.rb +254 -260
- data/lib/cmdx/result_ansi.rb +19 -85
- data/lib/cmdx/result_inspector.rb +27 -68
- data/lib/cmdx/result_logger.rb +18 -81
- data/lib/cmdx/result_serializer.rb +28 -132
- data/lib/cmdx/rspec/matchers.rb +28 -0
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +42 -0
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +57 -0
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +87 -0
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +51 -0
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +58 -0
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/have_context.rb +86 -0
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +54 -0
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +52 -0
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +114 -0
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +66 -0
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +64 -0
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +78 -0
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +76 -0
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +62 -0
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +85 -0
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +68 -0
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +92 -0
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +46 -0
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +181 -0
- data/lib/cmdx/task.rb +213 -425
- data/lib/cmdx/task_deprecator.rb +55 -0
- data/lib/cmdx/task_processor.rb +245 -0
- data/lib/cmdx/task_serializer.rb +22 -70
- data/lib/cmdx/utils/ansi_color.rb +13 -89
- data/lib/cmdx/utils/log_timestamp.rb +13 -42
- data/lib/cmdx/utils/monotonic_runtime.rb +13 -63
- data/lib/cmdx/utils/name_affix.rb +21 -71
- data/lib/cmdx/validator.rb +48 -0
- data/lib/cmdx/validator_registry.rb +86 -0
- data/lib/cmdx/validators/exclusion.rb +55 -94
- data/lib/cmdx/validators/format.rb +31 -85
- data/lib/cmdx/validators/inclusion.rb +65 -110
- data/lib/cmdx/validators/length.rb +117 -133
- data/lib/cmdx/validators/numeric.rb +123 -130
- data/lib/cmdx/validators/presence.rb +38 -79
- data/lib/cmdx/version.rb +1 -7
- data/lib/cmdx/workflow.rb +46 -339
- data/lib/cmdx.rb +1 -1
- data/lib/generators/cmdx/install_generator.rb +14 -31
- data/lib/generators/cmdx/task_generator.rb +39 -55
- data/lib/generators/cmdx/templates/install.rb +24 -6
- data/lib/generators/cmdx/workflow_generator.rb +41 -66
- data/lib/locales/ar.yml +0 -1
- data/lib/locales/cs.yml +0 -1
- data/lib/locales/da.yml +0 -1
- data/lib/locales/de.yml +0 -1
- data/lib/locales/el.yml +0 -1
- data/lib/locales/en.yml +0 -1
- data/lib/locales/es.yml +0 -1
- data/lib/locales/fi.yml +0 -1
- data/lib/locales/fr.yml +0 -1
- data/lib/locales/he.yml +0 -1
- data/lib/locales/hi.yml +0 -1
- data/lib/locales/it.yml +0 -1
- data/lib/locales/ja.yml +0 -1
- data/lib/locales/ko.yml +0 -1
- data/lib/locales/nl.yml +0 -1
- data/lib/locales/no.yml +0 -1
- data/lib/locales/pl.yml +0 -1
- data/lib/locales/pt.yml +0 -1
- data/lib/locales/ru.yml +0 -1
- data/lib/locales/sv.yml +0 -1
- data/lib/locales/th.yml +0 -1
- data/lib/locales/tr.yml +0 -1
- data/lib/locales/vi.yml +0 -1
- data/lib/locales/zh.yml +0 -1
- metadata +34 -8
- data/lib/cmdx/parameter_validator.rb +0 -81
- data/lib/cmdx/parameter_value.rb +0 -244
- data/lib/cmdx/parameters_inspector.rb +0 -72
- data/lib/cmdx/parameters_serializer.rb +0 -115
- data/lib/cmdx/rspec/result_matchers.rb +0 -917
- data/lib/cmdx/rspec/task_matchers.rb +0 -570
- data/lib/cmdx/validators/custom.rb +0 -102
@@ -1,75 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module CMDx
|
4
|
-
# Parameter inspection
|
4
|
+
# Parameter inspection and formatting utilities for readable parameter representation.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# @example Basic parameter inspection
|
11
|
-
# parameter_hash = {
|
12
|
-
# name: :user_id,
|
13
|
-
# type: :integer,
|
14
|
-
# source: :context,
|
15
|
-
# required: true,
|
16
|
-
# options: { numeric: { min: 1 } },
|
17
|
-
# children: []
|
18
|
-
# }
|
19
|
-
# ParameterInspector.call(parameter_hash)
|
20
|
-
# # => "Parameter: name=user_id type=integer source=context required=true options={numeric: {min: 1}}"
|
21
|
-
#
|
22
|
-
# @example Nested parameter inspection
|
23
|
-
# nested_parameter = {
|
24
|
-
# name: :address,
|
25
|
-
# type: :virtual,
|
26
|
-
# source: :context,
|
27
|
-
# required: true,
|
28
|
-
# options: {},
|
29
|
-
# children: [
|
30
|
-
# { name: :street, type: :string, source: :address, required: true, options: {}, children: [] }
|
31
|
-
# ]
|
32
|
-
# }
|
33
|
-
# ParameterInspector.call(nested_parameter)
|
34
|
-
# # => "Parameter: name=address type=virtual source=context required=true options={}
|
35
|
-
# # ↳ Parameter: name=street type=string source=address required=true options={}"
|
36
|
-
#
|
37
|
-
# @see CMDx::Parameter Parameter hash serialization via to_h
|
38
|
-
# @see CMDx::ParameterSerializer Parameter-to-hash conversion
|
6
|
+
# This module provides functionality to format parameter metadata into human-readable
|
7
|
+
# strings for debugging, logging, and introspection purposes. It handles nested
|
8
|
+
# parameter structures with proper indentation and displays essential parameter
|
9
|
+
# information in a structured format.
|
39
10
|
module ParameterInspector
|
40
11
|
|
41
|
-
# Ordered keys for consistent parameter inspection output.
|
42
|
-
#
|
43
|
-
# Defines the order in which parameter attributes are displayed
|
44
|
-
# in the inspection string, with children handled specially.
|
45
12
|
ORDERED_KEYS = %i[
|
46
13
|
name type source required options children
|
47
14
|
].freeze
|
48
15
|
|
49
16
|
module_function
|
50
17
|
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# Formats parameter data into a structured string with proper ordering
|
54
|
-
# and indentation for nested parameters. Child parameters are displayed
|
55
|
-
# with increased indentation and arrow prefixes.
|
18
|
+
# Formats a parameter hash into a human-readable string representation.
|
56
19
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
20
|
+
# This method converts parameter metadata into a structured string format
|
21
|
+
# that displays key parameter information in a consistent order. For parameters
|
22
|
+
# with nested children, it recursively formats child parameters with proper
|
23
|
+
# indentation to show the hierarchical structure.
|
60
24
|
#
|
61
|
-
# @
|
62
|
-
#
|
63
|
-
# # => "Parameter: name=user_id type=integer source=context required=true"
|
25
|
+
# @param parameter [Hash] the parameter hash to format
|
26
|
+
# @param depth [Integer] the current nesting depth for indentation (default: 1)
|
64
27
|
#
|
65
|
-
# @
|
66
|
-
# ParameterInspector.call(param_hash, 2)
|
67
|
-
# # => "Parameter: name=address type=virtual source=context required=true
|
68
|
-
# # ↳ Parameter: name=street type=string source=address required=true"
|
28
|
+
# @return [String] a formatted string representation of the parameter
|
69
29
|
#
|
70
|
-
# @example
|
71
|
-
#
|
72
|
-
#
|
30
|
+
# @example Format a parameter with nested children
|
31
|
+
# param = {
|
32
|
+
# name: :user, type: :hash, source: :context, required: false, options: {},
|
33
|
+
# children: [
|
34
|
+
# { name: :name, type: :string, source: :user, required: true, options: {}, children: [] },
|
35
|
+
# { name: :age, type: :integer, source: :user, required: false, options: {}, children: [] }
|
36
|
+
# ]
|
37
|
+
# }
|
38
|
+
# ParameterInspector.call(param)
|
39
|
+
# # => "Parameter: name=user type=hash source=context required=false options={}
|
40
|
+
# # ↳ Parameter: name=name type=string source=user required=true options={}
|
41
|
+
# # ↳ Parameter: name=age type=integer source=user required=false options={}"
|
73
42
|
def call(parameter, depth = 1)
|
74
43
|
ORDERED_KEYS.filter_map do |key|
|
75
44
|
value = parameter[key]
|
@@ -1,124 +1,99 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module CMDx
|
4
|
-
#
|
4
|
+
# Registry for managing parameter definitions and validation within tasks.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
#
|
10
|
-
# @example Basic parameter collection usage
|
11
|
-
# parameter_registry = ParameterRegistry.new
|
12
|
-
# parameter_registry << Parameter.new(:user_id, klass: Task, type: :integer)
|
13
|
-
# parameter_registry << Parameter.new(:email, klass: Task, type: :string)
|
14
|
-
# parameter_registry.valid? # => true (if all parameters are valid)
|
15
|
-
#
|
16
|
-
# @example Parameter collection validation
|
17
|
-
# parameter_registry.validate!(task_instance) # Validates all parameters
|
18
|
-
# parameter_registry.invalid? # => true if any parameter failed validation
|
19
|
-
#
|
20
|
-
# @example Parameter collection serialization
|
21
|
-
# parameter_registry.to_h # => Array of parameter hash representations
|
22
|
-
# parameter_registry.to_s # => Human-readable parameter descriptions
|
23
|
-
#
|
24
|
-
# @see CMDx::Parameter Individual parameter definitions
|
25
|
-
# @see CMDx::Task Task parameter integration
|
26
|
-
class ParameterRegistry < Array
|
6
|
+
# This registry handles the storage and validation of parameter definitions,
|
7
|
+
# including nested parameter structures and recursive validation logic.
|
8
|
+
class ParameterRegistry
|
27
9
|
|
28
|
-
#
|
10
|
+
# The internal array storing parameter definitions.
|
29
11
|
#
|
30
|
-
# @return [
|
12
|
+
# @return [Array] array containing parameter definition objects
|
13
|
+
attr_reader :registry
|
14
|
+
|
15
|
+
# Initializes a new parameter registry.
|
16
|
+
#
|
17
|
+
# @return [ParameterRegistry] a new parameter registry instance
|
31
18
|
#
|
32
|
-
# @example
|
33
|
-
#
|
34
|
-
def
|
35
|
-
|
19
|
+
# @example Creating an empty registry
|
20
|
+
# ParameterRegistry.new
|
21
|
+
def initialize
|
22
|
+
@registry = []
|
36
23
|
end
|
37
24
|
|
38
|
-
#
|
25
|
+
# Creates a deep copy of the parameter registry.
|
26
|
+
#
|
27
|
+
# @return [ParameterRegistry] a new registry instance with duplicated parameters
|
28
|
+
#
|
29
|
+
# @example Duplicating a registry
|
30
|
+
# original = ParameterRegistry.new
|
31
|
+
# copy = original.dup
|
32
|
+
def dup
|
33
|
+
new_registry = self.class.new
|
34
|
+
new_registry.instance_variable_set(:@registry, registry.map(&:dup))
|
35
|
+
new_registry
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks if all parameters in the registry are valid.
|
39
39
|
#
|
40
40
|
# @return [Boolean] true if all parameters are valid, false otherwise
|
41
41
|
#
|
42
|
-
# @example
|
43
|
-
#
|
42
|
+
# @example Checking registry validity
|
43
|
+
# registry.valid?
|
44
|
+
# # => true
|
44
45
|
def valid?
|
45
|
-
all?(&:valid?)
|
46
|
+
registry.all?(&:valid?)
|
46
47
|
end
|
47
48
|
|
48
|
-
# Validates all parameters in the
|
49
|
+
# Validates all parameters in the registry against a task instance.
|
49
50
|
#
|
50
|
-
#
|
51
|
-
# parameter accessor methods on the task instance, which triggers
|
52
|
-
# value resolution, coercion, and validation.
|
51
|
+
# @param task [Task] the task instance to validate parameters against
|
53
52
|
#
|
54
|
-
# @param task [CMDx::Task] The task instance to validate parameters against
|
55
53
|
# @return [void]
|
56
54
|
#
|
57
55
|
# @example Validating parameters
|
58
|
-
# task
|
59
|
-
# parameter_registry.validate!(task) # Validates all parameters
|
60
|
-
#
|
61
|
-
# @example Validation with nested parameters
|
62
|
-
# # Validates parent parameters and all nested child parameters
|
63
|
-
# parameter_registry.validate!(task_with_nested_params)
|
56
|
+
# registry.validate!(task)
|
64
57
|
def validate!(task)
|
65
|
-
each { |p| recursive_validate!(task, p) }
|
58
|
+
registry.each { |p| recursive_validate!(task, p) }
|
66
59
|
end
|
67
60
|
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
# @example
|
76
|
-
# parameter_registry.to_h
|
77
|
-
# # => [
|
78
|
-
# # {
|
79
|
-
# # source: :context,
|
80
|
-
# # name: :user_id,
|
81
|
-
# # type: :integer,
|
82
|
-
# # required: true,
|
83
|
-
# # options: {},
|
84
|
-
# # children: []
|
85
|
-
# # },
|
86
|
-
# # { ... }
|
87
|
-
# # ]
|
61
|
+
# Returns a hash representation of the registry.
|
62
|
+
#
|
63
|
+
# @return [Hash] serialized hash representation of all parameters
|
64
|
+
#
|
65
|
+
# @example Getting registry hash
|
66
|
+
# registry.to_h
|
67
|
+
# # => { name: { type: :string, required: true }, age: { type: :integer } }
|
88
68
|
def to_h
|
89
|
-
|
69
|
+
registry.map(&:to_h)
|
90
70
|
end
|
91
|
-
alias to_a to_h
|
92
71
|
|
93
|
-
#
|
94
|
-
#
|
95
|
-
# Creates a human-readable string representation of all parameters
|
96
|
-
# in the collection using the ParametersInspector.
|
72
|
+
# Returns a string representation of the registry.
|
97
73
|
#
|
98
|
-
# @return [String]
|
74
|
+
# @return [String] formatted string representation of all parameters
|
99
75
|
#
|
100
|
-
# @example
|
101
|
-
#
|
102
|
-
# # => "
|
103
|
-
# # Parameter: name=email type=string source=context required=false"
|
76
|
+
# @example Getting registry string
|
77
|
+
# registry.to_s
|
78
|
+
# # => "name (string, required), age (integer)"
|
104
79
|
def to_s
|
105
|
-
|
80
|
+
registry.map(&:to_s).join("\n")
|
106
81
|
end
|
107
82
|
|
108
83
|
private
|
109
84
|
|
110
|
-
# Recursively validates a parameter and
|
85
|
+
# Recursively validates a parameter and its children against a task.
|
111
86
|
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
# structures.
|
87
|
+
# @param task [Task] the task instance to validate against
|
88
|
+
# @param parameter [Parameter] the parameter to validate
|
115
89
|
#
|
116
|
-
# @param task [CMDx::Task] The task instance to validate against
|
117
|
-
# @param parameter [CMDx::Parameter] The parameter to validate
|
118
90
|
# @return [void]
|
91
|
+
#
|
92
|
+
# @example Recursive validation (internal use)
|
93
|
+
# recursive_validate!(task, parameter)
|
119
94
|
def recursive_validate!(task, parameter)
|
120
|
-
task.send(parameter.method_name)
|
121
|
-
parameter.children.each { |
|
95
|
+
task.send(parameter.method_name) # Make sure parameter is defined on task
|
96
|
+
parameter.children.each { |child| recursive_validate!(task, child) }
|
122
97
|
end
|
123
98
|
|
124
99
|
end
|
@@ -1,92 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module CMDx
|
4
|
-
# Parameter serialization
|
4
|
+
# Parameter serialization module for converting parameter objects to hash format.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# parameter = Parameter.new(:user_id, klass: Task, type: :integer, required: true)
|
12
|
-
# ParameterSerializer.call(parameter)
|
13
|
-
# # => {
|
14
|
-
# # source: :context,
|
15
|
-
# # name: :user_id,
|
16
|
-
# # type: :integer,
|
17
|
-
# # required: true,
|
18
|
-
# # options: {},
|
19
|
-
# # children: []
|
20
|
-
# # }
|
21
|
-
#
|
22
|
-
# @example Parameter with validation options
|
23
|
-
# parameter = Parameter.new(:email, klass: Task, type: :string,
|
24
|
-
# format: { with: /@/ }, presence: true)
|
25
|
-
# ParameterSerializer.call(parameter)
|
26
|
-
# # => {
|
27
|
-
# # source: :context,
|
28
|
-
# # name: :email,
|
29
|
-
# # type: :string,
|
30
|
-
# # required: false,
|
31
|
-
# # options: { format: { with: /@/ }, presence: true },
|
32
|
-
# # children: []
|
33
|
-
# # }
|
34
|
-
#
|
35
|
-
# @example Nested parameter serialization
|
36
|
-
# parent = Parameter.new(:address, klass: Task) do
|
37
|
-
# required :street, :city
|
38
|
-
# end
|
39
|
-
# ParameterSerializer.call(parent)
|
40
|
-
# # => {
|
41
|
-
# # source: :context,
|
42
|
-
# # name: :address,
|
43
|
-
# # type: :virtual,
|
44
|
-
# # required: false,
|
45
|
-
# # options: {},
|
46
|
-
# # children: [
|
47
|
-
# # { source: :address, name: :street, type: :virtual, required: true, options: {}, children: [] },
|
48
|
-
# # { source: :address, name: :city, type: :virtual, required: true, options: {}, children: [] }
|
49
|
-
# # ]
|
50
|
-
# # }
|
51
|
-
#
|
52
|
-
# @see CMDx::Parameter Parameter object creation and configuration
|
53
|
-
# @see CMDx::ParameterInspector Human-readable parameter formatting
|
6
|
+
# This module provides functionality to serialize parameter objects into a
|
7
|
+
# standardized hash representation that includes essential metadata about
|
8
|
+
# the parameter such as its source, name, type, required status, options,
|
9
|
+
# and child parameters. The serialized format is commonly used for debugging,
|
10
|
+
# logging, and introspection purposes.
|
54
11
|
module ParameterSerializer
|
55
12
|
|
56
13
|
module_function
|
57
14
|
|
58
|
-
#
|
15
|
+
# Serializes a parameter object into a hash representation.
|
59
16
|
#
|
60
|
-
#
|
61
|
-
# all relevant parameter information including source, name, type,
|
62
|
-
# requirement status, options, and recursively serialized children.
|
17
|
+
# @param parameter [Parameter] the parameter object to serialize
|
63
18
|
#
|
64
|
-
# @
|
65
|
-
# @return [Hash] Structured hash representation of the parameter
|
19
|
+
# @return [Hash] a hash containing the parameter's metadata
|
66
20
|
#
|
67
|
-
# @
|
68
|
-
# param = Parameter.new(:age, klass: Task, type: :integer, required: true)
|
69
|
-
# ParameterSerializer.call(param)
|
70
|
-
# # => {
|
71
|
-
# # source: :context,
|
72
|
-
# # name: :age,
|
73
|
-
# # type: :integer,
|
74
|
-
# # required: true,
|
75
|
-
# # options: {},
|
76
|
-
# # children: []
|
77
|
-
# # }
|
21
|
+
# @raise [NoMethodError] if the parameter doesn't respond to required methods
|
78
22
|
#
|
79
|
-
# @example
|
80
|
-
# param = Parameter.new(:
|
81
|
-
#
|
23
|
+
# @example Serialize a parameter with nested children
|
24
|
+
# param = Parameter.new(:user, klass: MyTask, type: :hash) do
|
25
|
+
# required :name, type: :string
|
26
|
+
# optional :age, type: :integer
|
27
|
+
# end
|
82
28
|
# ParameterSerializer.call(param)
|
83
29
|
# # => {
|
84
|
-
# # source: :
|
85
|
-
# # name: :
|
86
|
-
# # type: :
|
30
|
+
# # source: :context,
|
31
|
+
# # name: :user,
|
32
|
+
# # type: :hash,
|
87
33
|
# # required: false,
|
88
|
-
# # options: {
|
89
|
-
# # children: [
|
34
|
+
# # options: {},
|
35
|
+
# # children: [
|
36
|
+
# # { source: :user, name: :name, type: :string, required: true, options: {}, children: [] },
|
37
|
+
# # { source: :user, name: :age, type: :integer, required: false, options: {}, children: [] }
|
38
|
+
# # ]
|
90
39
|
# # }
|
91
40
|
def call(parameter)
|
92
41
|
{
|
data/lib/cmdx/railtie.rb
CHANGED
@@ -1,102 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module CMDx
|
4
|
-
|
5
|
-
# Railtie provides seamless integration between CMDx and Ruby on Rails applications.
|
6
|
-
# It automatically configures Rails-specific features including internationalization,
|
7
|
-
# autoloading paths, and directory structure conventions for CMDx tasks and workflows.
|
4
|
+
# Rails integration for CMDx framework.
|
8
5
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# 2. **Autoloading Setup**: Configures Rails autoloaders for CMDx command objects
|
12
|
-
#
|
13
|
-
# ## Directory Structure
|
14
|
-
#
|
15
|
-
# The Railtie expects CMDx command objects to be organized in the following structure:
|
16
|
-
# ```
|
17
|
-
# app/
|
18
|
-
# cmds/
|
19
|
-
# workflows/ # Workflow command objects
|
20
|
-
# order_processing_workflow.rb
|
21
|
-
# tasks/ # Task command objects
|
22
|
-
# process_order_task.rb
|
23
|
-
# send_email_task.rb
|
24
|
-
# ```
|
25
|
-
#
|
26
|
-
# ## Automatic Features
|
27
|
-
#
|
28
|
-
# When CMDx is included in a Rails application, the Railtie automatically:
|
29
|
-
# - Adds `app/cmds` to Rails autoload paths
|
30
|
-
# - Configures autoloader to collapse `app/cmds/workflows` and `app/cmds/tasks` directories
|
31
|
-
# - Loads appropriate locale files from CMDx gem for error messages and validations
|
32
|
-
# - Reloads I18n configuration to include CMDx translations
|
33
|
-
#
|
34
|
-
# @example Rails application structure
|
35
|
-
# # app/cmds/tasks/process_order_task.rb
|
36
|
-
# class ProcessOrderTask < CMDx::Task
|
37
|
-
# required :order_id, type: :integer
|
38
|
-
#
|
39
|
-
# def call
|
40
|
-
# context.order = Order.find(order_id)
|
41
|
-
# context.order.process!
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# @example Using in Rails controllers
|
46
|
-
# class OrdersController < ApplicationController
|
47
|
-
# def process
|
48
|
-
# result = ProcessOrderTask.call(order_id: params[:id])
|
49
|
-
#
|
50
|
-
# if result.success?
|
51
|
-
# redirect_to order_path(result.context.order), notice: 'Order processed!'
|
52
|
-
# else
|
53
|
-
# redirect_to order_path(params[:id]), alert: result.metadata[:reason]
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# @example I18n integration
|
59
|
-
# # CMDx automatically loads locale files for validation messages
|
60
|
-
# # en.yml, es.yml, etc. are automatically available
|
61
|
-
# result = MyTask.call(invalid_param: nil)
|
62
|
-
# result.errors.full_messages # Uses localized error messages
|
63
|
-
#
|
64
|
-
# @see Configuration Configuration options for Rails integration
|
65
|
-
# @see Task Task base class for command objects
|
66
|
-
# @see Workflow Workflow base class for multi-task operations
|
67
|
-
# @since 1.0.0
|
6
|
+
# Provides Rails-specific configuration including internationalization
|
7
|
+
# locale loading and autoload path configuration for CMDx workflows and tasks.
|
68
8
|
class Railtie < Rails::Railtie
|
69
9
|
|
70
10
|
railtie_name :cmdx
|
71
11
|
|
72
|
-
|
73
|
-
# Configures internationalization (I18n) for CMDx in Rails applications.
|
74
|
-
# Automatically loads locale files from the CMDx gem for all configured
|
75
|
-
# application locales, ensuring error messages and validations are properly localized.
|
12
|
+
# Configure internationalization locales for CMDx.
|
76
13
|
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# 3. Adds found locale files to I18n load path
|
81
|
-
# 4. Reloads I18n configuration
|
14
|
+
# Loads available locale files from the CMDx locales directory
|
15
|
+
# and adds them to the I18n load path. Only loads locales that
|
16
|
+
# are configured as available in the Rails application.
|
82
17
|
#
|
83
18
|
# @param app [Rails::Application] the Rails application instance
|
84
|
-
# @return [void]
|
85
19
|
#
|
86
|
-
# @
|
87
|
-
# # If Rails app has config.i18n.available_locales = [:en, :es]
|
88
|
-
# # This will load:
|
89
|
-
# # - lib/locales/en.yml (CMDx English translations)
|
90
|
-
# # - lib/locales/es.yml (CMDx Spanish translations)
|
20
|
+
# @return [void]
|
91
21
|
#
|
92
|
-
# @
|
93
|
-
# # With Spanish locale active
|
94
|
-
# class MyTask < CMDx::Task
|
95
|
-
# required :name, presence: true
|
96
|
-
# end
|
22
|
+
# @raise [StandardError] if I18n reload fails
|
97
23
|
#
|
98
|
-
#
|
99
|
-
#
|
24
|
+
# @example Configure locales during Rails initialization
|
25
|
+
# # This initializer runs automatically during Rails boot
|
26
|
+
# # when CMDx is included in a Rails application
|
100
27
|
initializer("cmdx.configure_locales") do |app|
|
101
28
|
Array(app.config.i18n.available_locales).each do |locale|
|
102
29
|
path = File.expand_path("../../../lib/locales/#{locale}.yml", __FILE__)
|
@@ -108,34 +35,24 @@ module CMDx
|
|
108
35
|
I18n.reload!
|
109
36
|
end
|
110
37
|
|
111
|
-
|
112
|
-
# Configures Rails autoloading for CMDx command objects.
|
113
|
-
# Sets up proper autoloading paths and directory collapsing to ensure
|
114
|
-
# CMDx tasks and workflows are loaded correctly in Rails applications.
|
38
|
+
# Configure Rails autoload paths for CMDx components.
|
115
39
|
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
# Directory collapsing means that files in `app/cmds/tasks/` will be loaded
|
122
|
-
# as if they were directly in `app/cmds/`, allowing for better organization
|
123
|
-
# without affecting class naming conventions.
|
40
|
+
# Adds the app/cmds directory to Rails autoload paths and configures
|
41
|
+
# autoloaders to collapse the workflows and tasks subdirectories.
|
42
|
+
# This enables Rails to automatically load CMDx workflows and tasks
|
43
|
+
# from the conventional directory structure.
|
124
44
|
#
|
125
45
|
# @param app [Rails::Application] the Rails application instance
|
126
|
-
# @return [void]
|
127
46
|
#
|
128
|
-
# @
|
129
|
-
# # File: app/cmds/tasks/process_order_task.rb
|
130
|
-
# # Class: ProcessOrderTask (not Tasks::ProcessOrderTask)
|
47
|
+
# @return [void]
|
131
48
|
#
|
132
|
-
#
|
133
|
-
# # Class: OrderProcessingWorkflow (not Workflows::OrderProcessingWorkflow)
|
49
|
+
# @raise [StandardError] if autoloader configuration fails
|
134
50
|
#
|
135
|
-
# @example
|
136
|
-
# #
|
137
|
-
#
|
138
|
-
#
|
51
|
+
# @example Configure autoload paths during Rails initialization
|
52
|
+
# # This initializer runs automatically during Rails boot
|
53
|
+
# # Enables loading of:
|
54
|
+
# # - app/cmds/workflows/my_workflow.rb
|
55
|
+
# # - app/cmds/tasks/my_task.rb
|
139
56
|
initializer("cmdx.configure_rails_auto_load_paths") do |app|
|
140
57
|
app.config.autoload_paths += %w[app/cmds]
|
141
58
|
|