typed_operation 1.0.0.pre2 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +79 -574
  3. data/lib/generators/templates/operation.rb +2 -2
  4. data/lib/generators/typed_operation/install/USAGE +1 -0
  5. data/lib/generators/typed_operation/install/install_generator.rb +8 -0
  6. data/lib/generators/typed_operation/install/templates/application_operation.rb +24 -2
  7. data/lib/generators/typed_operation_generator.rb +8 -4
  8. data/lib/typed_operation/action_policy_auth.rb +161 -0
  9. data/lib/typed_operation/base.rb +5 -13
  10. data/lib/typed_operation/callable_resolver.rb +30 -0
  11. data/lib/typed_operation/chains/chained_operation.rb +27 -0
  12. data/lib/typed_operation/chains/fallback_chain.rb +32 -0
  13. data/lib/typed_operation/chains/map_chain.rb +37 -0
  14. data/lib/typed_operation/chains/sequence_chain.rb +54 -0
  15. data/lib/typed_operation/chains/smart_chain.rb +161 -0
  16. data/lib/typed_operation/chains/splat_chain.rb +53 -0
  17. data/lib/typed_operation/configuration.rb +52 -0
  18. data/lib/typed_operation/context.rb +193 -0
  19. data/lib/typed_operation/curried.rb +14 -1
  20. data/lib/typed_operation/explainable.rb +14 -0
  21. data/lib/typed_operation/immutable_base.rb +5 -2
  22. data/lib/typed_operation/instrumentation/trace.rb +71 -0
  23. data/lib/typed_operation/instrumentation/tree_formatter.rb +141 -0
  24. data/lib/typed_operation/instrumentation.rb +214 -0
  25. data/lib/typed_operation/operations/composition.rb +41 -0
  26. data/lib/typed_operation/operations/executable.rb +55 -0
  27. data/lib/typed_operation/operations/introspection.rb +14 -8
  28. data/lib/typed_operation/operations/lifecycle.rb +5 -1
  29. data/lib/typed_operation/operations/parameters.rb +21 -6
  30. data/lib/typed_operation/operations/partial_application.rb +4 -0
  31. data/lib/typed_operation/operations/property_builder.rb +105 -0
  32. data/lib/typed_operation/partially_applied.rb +33 -10
  33. data/lib/typed_operation/pipeline/builder.rb +88 -0
  34. data/lib/typed_operation/pipeline/chainable_wrapper.rb +23 -0
  35. data/lib/typed_operation/pipeline/empty_pipeline_chain.rb +25 -0
  36. data/lib/typed_operation/pipeline/step_wrapper.rb +94 -0
  37. data/lib/typed_operation/pipeline.rb +176 -0
  38. data/lib/typed_operation/prepared.rb +13 -0
  39. data/lib/typed_operation/railtie.rb +4 -0
  40. data/lib/typed_operation/result/adapters/built_in.rb +28 -0
  41. data/lib/typed_operation/result/adapters/dry_monads.rb +36 -0
  42. data/lib/typed_operation/result/failure.rb +78 -0
  43. data/lib/typed_operation/result/mixin.rb +24 -0
  44. data/lib/typed_operation/result/success.rb +75 -0
  45. data/lib/typed_operation/result.rb +39 -0
  46. data/lib/typed_operation/version.rb +5 -1
  47. data/lib/typed_operation.rb +19 -6
  48. metadata +59 -18
  49. data/Rakefile +0 -17
  50. data/lib/tasks/typed_operation_tasks.rake +0 -4
  51. data/lib/typed_operation/operations/attribute_builder.rb +0 -75
  52. data/lib/typed_operation/operations/callable.rb +0 -27
  53. 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.pre2"
5
+ #: String
6
+ VERSION = "1.0.0"
3
7
  end
@@ -1,24 +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"
14
+ require "typed_operation/operations/executable"
15
+ require "typed_operation/operations/composition"
16
16
  require "typed_operation/curried"
17
+ require "typed_operation/instrumentation"
18
+ require "typed_operation/explainable"
17
19
  require "typed_operation/immutable_base"
18
20
  require "typed_operation/base"
19
21
  require "typed_operation/partially_applied"
20
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"
21
32
 
33
+ # TypedOperation provides a framework for defining type-safe, composable operations
34
+ # with support for partial application, currying, and parameter validation.
22
35
  module TypedOperation
23
36
  class InvalidOperationError < StandardError; end
24
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.pre2
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-22 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,21 +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
68
+ - lib/typed_operation/operations/executable.rb
39
69
  - lib/typed_operation/operations/introspection.rb
40
70
  - lib/typed_operation/operations/lifecycle.rb
41
71
  - lib/typed_operation/operations/parameters.rb
42
72
  - lib/typed_operation/operations/partial_application.rb
73
+ - lib/typed_operation/operations/property_builder.rb
43
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
44
80
  - lib/typed_operation/prepared.rb
45
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
46
88
  - lib/typed_operation/version.rb
47
89
  homepage: https://github.com/stevegeek/typed_operation
48
90
  licenses:
@@ -50,7 +92,6 @@ licenses:
50
92
  metadata:
51
93
  homepage_uri: https://github.com/stevegeek/typed_operation
52
94
  source_code_uri: https://github.com/stevegeek/typed_operation
53
- post_install_message:
54
95
  rdoc_options: []
55
96
  require_paths:
56
97
  - lib
@@ -58,15 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
99
  requirements:
59
100
  - - ">="
60
101
  - !ruby/object:Gem::Version
61
- version: '3.1'
102
+ version: '3.2'
62
103
  required_rubygems_version: !ruby/object:Gem::Requirement
63
104
  requirements:
64
- - - ">"
105
+ - - ">="
65
106
  - !ruby/object:Gem::Version
66
- version: 1.3.1
107
+ version: '0'
67
108
  requirements: []
68
- rubygems_version: 3.4.18
69
- signing_key:
109
+ rubygems_version: 4.0.3
70
110
  specification_version: 4
71
- 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.
72
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,75 +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
- @typed_operation.attribute(
21
- @name,
22
- @signature,
23
- default: default_value_for_literal,
24
- positional: @positional,
25
- reader: @reader,
26
- &converter
27
- )
28
- end
29
-
30
- private
31
-
32
- def prepare_type_signature_for_literal
33
- @signature = Literal::Types::NilableType.new(@signature) if needs_to_be_nilable?
34
- union_with_nil_to_support_nil_default
35
- validate_positional_order_params! if @positional
36
- end
37
-
38
- # If already wrapped in a Nilable then don't wrap again
39
- def needs_to_be_nilable?
40
- @optional && !type_nilable?
41
- end
42
-
43
- def type_nilable?
44
- @signature.is_a?(Literal::Types::NilableType)
45
- end
46
-
47
- def union_with_nil_to_support_nil_default
48
- @signature = Literal::Union.new(@signature, NilClass) if has_default_value_nil?
49
- end
50
-
51
- def has_default_value_nil?
52
- default_provided? && @default.nil?
53
- end
54
-
55
- def validate_positional_order_params!
56
- # Optional ones can always be added after required ones, or before any others, but required ones must be first
57
- unless type_nilable? || @typed_operation.optional_positional_parameters.empty?
58
- raise ParameterError, "Cannot define required positional parameter '#{@name}' after optional positional parameters"
59
- end
60
- end
61
-
62
- def default_provided?
63
- @default_key
64
- end
65
-
66
- def default_value_for_literal
67
- if has_default_value_nil? || type_nilable?
68
- -> {}
69
- else
70
- @default
71
- end
72
- end
73
- end
74
- end
75
- end
@@ -1,27 +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
-
22
- def call
23
- raise InvalidOperationError, "You must implement #call"
24
- end
25
- end
26
- end
27
- 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