typed_operation 1.0.0.pre3 → 1.0.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -624
  3. data/lib/generators/typed_operation/install/USAGE +1 -0
  4. data/lib/generators/typed_operation/install/install_generator.rb +8 -0
  5. data/lib/generators/typed_operation/install/templates/application_operation.rb +24 -2
  6. data/lib/generators/typed_operation_generator.rb +8 -4
  7. data/lib/typed_operation/action_policy_auth.rb +161 -0
  8. data/lib/typed_operation/base.rb +4 -13
  9. data/lib/typed_operation/callable_resolver.rb +30 -0
  10. data/lib/typed_operation/chains/chained_operation.rb +27 -0
  11. data/lib/typed_operation/chains/fallback_chain.rb +32 -0
  12. data/lib/typed_operation/chains/map_chain.rb +37 -0
  13. data/lib/typed_operation/chains/sequence_chain.rb +54 -0
  14. data/lib/typed_operation/chains/smart_chain.rb +161 -0
  15. data/lib/typed_operation/chains/splat_chain.rb +53 -0
  16. data/lib/typed_operation/configuration.rb +52 -0
  17. data/lib/typed_operation/context.rb +193 -0
  18. data/lib/typed_operation/curried.rb +14 -1
  19. data/lib/typed_operation/explainable.rb +14 -0
  20. data/lib/typed_operation/immutable_base.rb +4 -2
  21. data/lib/typed_operation/instrumentation/trace.rb +71 -0
  22. data/lib/typed_operation/instrumentation/tree_formatter.rb +141 -0
  23. data/lib/typed_operation/instrumentation.rb +214 -0
  24. data/lib/typed_operation/operations/composition.rb +41 -0
  25. data/lib/typed_operation/operations/executable.rb +27 -1
  26. data/lib/typed_operation/operations/introspection.rb +14 -8
  27. data/lib/typed_operation/operations/lifecycle.rb +5 -2
  28. data/lib/typed_operation/operations/parameters.rb +21 -6
  29. data/lib/typed_operation/operations/partial_application.rb +4 -0
  30. data/lib/typed_operation/operations/property_builder.rb +105 -0
  31. data/lib/typed_operation/partially_applied.rb +33 -10
  32. data/lib/typed_operation/pipeline/builder.rb +88 -0
  33. data/lib/typed_operation/pipeline/chainable_wrapper.rb +23 -0
  34. data/lib/typed_operation/pipeline/empty_pipeline_chain.rb +25 -0
  35. data/lib/typed_operation/pipeline/step_wrapper.rb +94 -0
  36. data/lib/typed_operation/pipeline.rb +176 -0
  37. data/lib/typed_operation/prepared.rb +13 -0
  38. data/lib/typed_operation/railtie.rb +4 -0
  39. data/lib/typed_operation/result/adapters/built_in.rb +28 -0
  40. data/lib/typed_operation/result/adapters/dry_monads.rb +36 -0
  41. data/lib/typed_operation/result/failure.rb +78 -0
  42. data/lib/typed_operation/result/mixin.rb +24 -0
  43. data/lib/typed_operation/result/success.rb +75 -0
  44. data/lib/typed_operation/result.rb +39 -0
  45. data/lib/typed_operation/version.rb +5 -1
  46. data/lib/typed_operation.rb +18 -6
  47. metadata +58 -18
  48. data/Rakefile +0 -17
  49. data/lib/tasks/typed_operation_tasks.rake +0 -4
  50. data/lib/typed_operation/operations/attribute_builder.rb +0 -81
  51. data/lib/typed_operation/operations/callable.rb +0 -23
  52. data/lib/typed_operation/operations/deconstruct.rb +0 -16
@@ -0,0 +1,39 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "result/success"
5
+ require_relative "result/failure"
6
+ require_relative "result/adapters/built_in"
7
+ require_relative "result/adapters/dry_monads"
8
+ require_relative "result/mixin"
9
+
10
+ module TypedOperation
11
+ # Result types for representing success and failure outcomes.
12
+ #
13
+ # TypedOperation provides built-in Success and Failure types that work
14
+ # out of the box. You can also configure it to use Dry::Monads or a
15
+ # custom adapter.
16
+ #
17
+ # @example Default usage (built-in types)
18
+ # result = MyPipeline.call(input)
19
+ # result.success? # => true or false
20
+ # result.value! # => the value (raises on failure)
21
+ #
22
+ # @example Configure to use Dry::Monads
23
+ # TypedOperation.configure do |config|
24
+ # config.result_adapter = :dry_monads
25
+ # end
26
+ #
27
+ # @example Pattern matching
28
+ # case result
29
+ # in Success[value]
30
+ # handle_success(value)
31
+ # in Failure[error]
32
+ # handle_failure(error)
33
+ # end
34
+ #
35
+ module Result
36
+ # Alias for easy access to UnwrapError from Result module
37
+ UnwrapError = TypedOperation::UnwrapError
38
+ end
39
+ end
@@ -1,3 +1,7 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
1
4
  module TypedOperation
2
- VERSION = "1.0.0.pre3"
5
+ #: String
6
+ VERSION = "1.0.0"
3
7
  end
@@ -1,25 +1,37 @@
1
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2.0")
2
- require "polyfill-data"
3
- end
1
+ # rbs_inline: enabled
4
2
 
5
3
  require "literal"
6
4
 
7
5
  require "typed_operation/version"
8
6
  require "typed_operation/railtie" if defined?(Rails::Railtie)
7
+ require "typed_operation/result"
8
+ require "typed_operation/configuration"
9
9
  require "typed_operation/operations/introspection"
10
10
  require "typed_operation/operations/parameters"
11
11
  require "typed_operation/operations/partial_application"
12
- require "typed_operation/operations/callable"
13
12
  require "typed_operation/operations/lifecycle"
14
- require "typed_operation/operations/deconstruct"
15
- require "typed_operation/operations/attribute_builder"
13
+ require "typed_operation/operations/property_builder"
16
14
  require "typed_operation/operations/executable"
15
+ require "typed_operation/operations/composition"
17
16
  require "typed_operation/curried"
17
+ require "typed_operation/instrumentation"
18
+ require "typed_operation/explainable"
18
19
  require "typed_operation/immutable_base"
19
20
  require "typed_operation/base"
20
21
  require "typed_operation/partially_applied"
21
22
  require "typed_operation/prepared"
23
+ require "typed_operation/callable_resolver"
24
+ require "typed_operation/chains/chained_operation"
25
+ require "typed_operation/chains/sequence_chain"
26
+ require "typed_operation/chains/splat_chain"
27
+ require "typed_operation/chains/smart_chain"
28
+ require "typed_operation/chains/map_chain"
29
+ require "typed_operation/chains/fallback_chain"
30
+ require "typed_operation/context"
31
+ require "typed_operation/pipeline"
22
32
 
33
+ # TypedOperation provides a framework for defining type-safe, composable operations
34
+ # with support for partial application, currying, and parameter validation.
23
35
  module TypedOperation
24
36
  class InvalidOperationError < StandardError; end
25
37
 
metadata CHANGED
@@ -1,17 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typed_operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-08-25 00:00:00.000000000 Z
12
- dependencies: []
13
- description: TypedOperation is a command pattern implementation where inputs can be
14
- defined with runtime type checks. Operations can be partially applied.
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: literal
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 1.9.0
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 1.9.0
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: 2.0.0
32
+ description: Command pattern, which is callable, and can be partially applied, curried
33
+ and has typed parameters. Authorization to execute via action_policy if desired.
15
34
  email:
16
35
  - stevegeek@gmail.com
17
36
  executables: []
@@ -20,7 +39,6 @@ extra_rdoc_files: []
20
39
  files:
21
40
  - MIT-LICENSE
22
41
  - README.md
23
- - Rakefile
24
42
  - lib/generators/USAGE
25
43
  - lib/generators/templates/operation.rb
26
44
  - lib/generators/templates/operation_test.rb
@@ -28,22 +46,45 @@ files:
28
46
  - lib/generators/typed_operation/install/install_generator.rb
29
47
  - lib/generators/typed_operation/install/templates/application_operation.rb
30
48
  - lib/generators/typed_operation_generator.rb
31
- - lib/tasks/typed_operation_tasks.rake
32
49
  - lib/typed_operation.rb
50
+ - lib/typed_operation/action_policy_auth.rb
33
51
  - lib/typed_operation/base.rb
52
+ - lib/typed_operation/callable_resolver.rb
53
+ - lib/typed_operation/chains/chained_operation.rb
54
+ - lib/typed_operation/chains/fallback_chain.rb
55
+ - lib/typed_operation/chains/map_chain.rb
56
+ - lib/typed_operation/chains/sequence_chain.rb
57
+ - lib/typed_operation/chains/smart_chain.rb
58
+ - lib/typed_operation/chains/splat_chain.rb
59
+ - lib/typed_operation/configuration.rb
60
+ - lib/typed_operation/context.rb
34
61
  - lib/typed_operation/curried.rb
62
+ - lib/typed_operation/explainable.rb
35
63
  - lib/typed_operation/immutable_base.rb
36
- - lib/typed_operation/operations/attribute_builder.rb
37
- - lib/typed_operation/operations/callable.rb
38
- - lib/typed_operation/operations/deconstruct.rb
64
+ - lib/typed_operation/instrumentation.rb
65
+ - lib/typed_operation/instrumentation/trace.rb
66
+ - lib/typed_operation/instrumentation/tree_formatter.rb
67
+ - lib/typed_operation/operations/composition.rb
39
68
  - lib/typed_operation/operations/executable.rb
40
69
  - lib/typed_operation/operations/introspection.rb
41
70
  - lib/typed_operation/operations/lifecycle.rb
42
71
  - lib/typed_operation/operations/parameters.rb
43
72
  - lib/typed_operation/operations/partial_application.rb
73
+ - lib/typed_operation/operations/property_builder.rb
44
74
  - lib/typed_operation/partially_applied.rb
75
+ - lib/typed_operation/pipeline.rb
76
+ - lib/typed_operation/pipeline/builder.rb
77
+ - lib/typed_operation/pipeline/chainable_wrapper.rb
78
+ - lib/typed_operation/pipeline/empty_pipeline_chain.rb
79
+ - lib/typed_operation/pipeline/step_wrapper.rb
45
80
  - lib/typed_operation/prepared.rb
46
81
  - lib/typed_operation/railtie.rb
82
+ - lib/typed_operation/result.rb
83
+ - lib/typed_operation/result/adapters/built_in.rb
84
+ - lib/typed_operation/result/adapters/dry_monads.rb
85
+ - lib/typed_operation/result/failure.rb
86
+ - lib/typed_operation/result/mixin.rb
87
+ - lib/typed_operation/result/success.rb
47
88
  - lib/typed_operation/version.rb
48
89
  homepage: https://github.com/stevegeek/typed_operation
49
90
  licenses:
@@ -51,7 +92,6 @@ licenses:
51
92
  metadata:
52
93
  homepage_uri: https://github.com/stevegeek/typed_operation
53
94
  source_code_uri: https://github.com/stevegeek/typed_operation
54
- post_install_message:
55
95
  rdoc_options: []
56
96
  require_paths:
57
97
  - lib
@@ -59,15 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
99
  requirements:
60
100
  - - ">="
61
101
  - !ruby/object:Gem::Version
62
- version: '3.1'
102
+ version: '3.2'
63
103
  required_rubygems_version: !ruby/object:Gem::Requirement
64
104
  requirements:
65
- - - ">"
105
+ - - ">="
66
106
  - !ruby/object:Gem::Version
67
- version: 1.3.1
107
+ version: '0'
68
108
  requirements: []
69
- rubygems_version: 3.4.18
70
- signing_key:
109
+ rubygems_version: 4.0.3
71
110
  specification_version: 4
72
- summary: TypedOperation is a command pattern implementation
111
+ summary: TypedOperation is a command pattern with typed parameters, which is callable,
112
+ and can be partially applied.
73
113
  test_files: []
data/Rakefile DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "bundler/setup"
5
- require "rake/testtask"
6
-
7
- ENV["NO_RAILS"] = "true"
8
-
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << "test"
11
- t.libs << "lib"
12
- t.test_files = FileList["test/typed_operation/**/*_test.rb"]
13
- end
14
-
15
- require "standard/rake"
16
-
17
- task default: %i[test standard]
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :typed_operation do
3
- # # Task goes here
4
- # end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TypedOperation
4
- module Operations
5
- class AttributeBuilder
6
- def initialize(typed_operation, parameter_name, type_signature, options)
7
- @typed_operation = typed_operation
8
- @name = parameter_name
9
- @signature = type_signature
10
- @optional = options[:optional]
11
- @positional = options[:positional]
12
- @reader = options[:reader] || :public
13
- @default_key = options.key?(:default)
14
- @default = options[:default]
15
-
16
- prepare_type_signature_for_literal
17
- end
18
-
19
- def define(&converter)
20
- # If nilable, then converter should not attempt to call the type converter block if the value is nil
21
- coerce_by = if type_nilable? && converter
22
- ->(v) { (v == Literal::Null || v.nil?) ? v : converter.call(v) }
23
- else
24
- converter
25
- end
26
- @typed_operation.attribute(
27
- @name,
28
- @signature,
29
- default: default_value_for_literal,
30
- positional: @positional,
31
- reader: @reader,
32
- &coerce_by
33
- )
34
- end
35
-
36
- private
37
-
38
- def prepare_type_signature_for_literal
39
- @signature = Literal::Types::NilableType.new(@signature) if needs_to_be_nilable?
40
- union_with_nil_to_support_nil_default
41
- validate_positional_order_params! if @positional
42
- end
43
-
44
- # If already wrapped in a Nilable then don't wrap again
45
- def needs_to_be_nilable?
46
- @optional && !type_nilable?
47
- end
48
-
49
- def type_nilable?
50
- @signature.is_a?(Literal::Types::NilableType)
51
- end
52
-
53
- def union_with_nil_to_support_nil_default
54
- @signature = Literal::Union.new(@signature, NilClass) if has_default_value_nil?
55
- end
56
-
57
- def has_default_value_nil?
58
- default_provided? && @default.nil?
59
- end
60
-
61
- def validate_positional_order_params!
62
- # Optional ones can always be added after required ones, or before any others, but required ones must be first
63
- unless type_nilable? || @typed_operation.optional_positional_parameters.empty?
64
- raise ParameterError, "Cannot define required positional parameter '#{@name}' after optional positional parameters"
65
- end
66
- end
67
-
68
- def default_provided?
69
- @default_key
70
- end
71
-
72
- def default_value_for_literal
73
- if has_default_value_nil? || type_nilable?
74
- -> {}
75
- else
76
- @default
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TypedOperation
4
- module Operations
5
- module Callable
6
- def self.included(base)
7
- base.extend(CallableMethods)
8
- end
9
-
10
- module CallableMethods
11
- def call(...)
12
- new(...).call
13
- end
14
-
15
- def to_proc
16
- method(:call).to_proc
17
- end
18
- end
19
-
20
- include CallableMethods
21
- end
22
- end
23
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TypedOperation
4
- module Operations
5
- module Deconstruct
6
- def deconstruct
7
- attributes.values
8
- end
9
-
10
- def deconstruct_keys(keys)
11
- h = attributes.to_h
12
- keys ? h.slice(*keys) : h
13
- end
14
- end
15
- end
16
- end