action_figure 0.1.0 → 0.6.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/LICENSE.txt +1 -1
- data/README.md +219 -16
- data/docs/actions.md +495 -0
- data/docs/activesupport-notifications.md +113 -0
- data/docs/configuration.md +88 -0
- data/docs/custom-formatters.md +185 -0
- data/docs/integration-patterns.md +331 -0
- data/docs/response-formatters.md +1088 -0
- data/docs/status-codes.md +35 -0
- data/docs/testing.md +272 -0
- data/docs/validation.md +294 -0
- data/lib/action_figure/configuration.rb +33 -0
- data/lib/action_figure/core.rb +200 -0
- data/lib/action_figure/format_registry.rb +40 -0
- data/lib/action_figure/formatter.rb +14 -0
- data/lib/action_figure/formatters/default.rb +49 -0
- data/lib/action_figure/formatters/jsend.rb +49 -0
- data/lib/action_figure/formatters/json_api/resource.rb +30 -0
- data/lib/action_figure/formatters/json_api.rb +65 -0
- data/lib/action_figure/formatters/wrapped.rb +49 -0
- data/lib/action_figure/testing/minitest.rb +58 -0
- data/lib/action_figure/testing/rspec.rb +44 -0
- data/lib/action_figure/version.rb +1 -1
- data/lib/action_figure.rb +68 -0
- data/sig/action_figure.rbs +157 -1
- metadata +26 -5
data/sig/action_figure.rbs
CHANGED
|
@@ -1,4 +1,160 @@
|
|
|
1
|
+
# Type definitions for the ActionFigure gem
|
|
2
|
+
|
|
3
|
+
# Response hash returned by formatter methods
|
|
4
|
+
type ActionFigure::response = { json: Hash[Symbol, untyped], status: Symbol } | { status: Symbol }
|
|
5
|
+
|
|
6
|
+
# Error hash mapping field names to arrays of error messages
|
|
7
|
+
type ActionFigure::error_hash = Hash[Symbol, Array[String]]
|
|
8
|
+
|
|
1
9
|
module ActionFigure
|
|
2
10
|
VERSION: String
|
|
3
|
-
|
|
11
|
+
|
|
12
|
+
class IndeterminantEntryPointError < StandardError
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
extend Configuration
|
|
16
|
+
extend FormatRegistry
|
|
17
|
+
|
|
18
|
+
def self.[]: (?Symbol format) -> Module
|
|
19
|
+
def self.included: (Module base) -> void
|
|
20
|
+
def self.register_formatter: (**Module formatters) -> void
|
|
21
|
+
def self.clear_format_module_cache: (Symbol name) -> void
|
|
22
|
+
|
|
23
|
+
# Provides global configuration via ActionFigure.configure
|
|
24
|
+
module Configuration
|
|
25
|
+
class Settings
|
|
26
|
+
attr_accessor format: Symbol
|
|
27
|
+
attr_accessor whiny_extra_params: bool
|
|
28
|
+
attr_accessor api_version: untyped
|
|
29
|
+
attr_accessor activesupport_notifications: bool
|
|
30
|
+
|
|
31
|
+
def initialize: () -> void
|
|
32
|
+
def configure: () { (Settings) -> void } -> void
|
|
33
|
+
def register: (**Module formatters) -> void
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def configure: () { (Settings) -> void } -> void
|
|
37
|
+
def configuration: () -> Settings
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Provides formatter registration and lookup
|
|
41
|
+
module FormatRegistry
|
|
42
|
+
class Formats
|
|
43
|
+
def initialize: () -> void
|
|
44
|
+
def register_formatter: (**Module formatters) -> void
|
|
45
|
+
def fetch: (Symbol name) -> Module
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def register_formatter: (**Module formatters) -> void
|
|
49
|
+
def fetch: (Symbol name) -> Module
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Base module for response formatters
|
|
53
|
+
module Formatter
|
|
54
|
+
REQUIRED_METHODS: Array[Symbol]
|
|
55
|
+
|
|
56
|
+
def NoContent: () -> ActionFigure::response
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Validation pipeline and DSL mixed into action classes
|
|
60
|
+
module Core
|
|
61
|
+
# Cross-parameter rule helpers for dry-validation contracts
|
|
62
|
+
module CrossParamRuleHelpers
|
|
63
|
+
def exclusive_rule: (*Symbol fields, String message) -> void
|
|
64
|
+
def any_rule: (*Symbol fields, String message) -> void
|
|
65
|
+
def one_rule: (*Symbol fields, String message) -> void
|
|
66
|
+
def all_rule: (*Symbol fields, String message) -> void
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Class-level DSL extended into action classes
|
|
70
|
+
module ClassMethods
|
|
71
|
+
def params_schema: () { () -> void } -> void
|
|
72
|
+
def rules: () { () -> void } -> void
|
|
73
|
+
def entry_point: (Symbol name) -> void
|
|
74
|
+
def entry_point_name: () -> Symbol?
|
|
75
|
+
def api_version: (?untyped value) -> untyped
|
|
76
|
+
def contract: () -> untyped
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def entry_point_name: () -> Symbol
|
|
80
|
+
def contract: () -> untyped
|
|
81
|
+
def validated_call: (**untyped kwargs) -> ActionFigure::response
|
|
82
|
+
|
|
83
|
+
# ActiveSupport::Notifications instrumentation
|
|
84
|
+
module Notifications
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
module Formatters
|
|
89
|
+
# Rails-style responses with { data: } envelope
|
|
90
|
+
module Default
|
|
91
|
+
include ActionFigure::Formatter
|
|
92
|
+
|
|
93
|
+
def Ok: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
94
|
+
def Created: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
95
|
+
def Accepted: (?resource: untyped?, ?meta: untyped?) -> ActionFigure::response
|
|
96
|
+
def UnprocessableContent: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
97
|
+
def NotFound: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
98
|
+
def Forbidden: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# JSend-formatted responses
|
|
102
|
+
module Jsend
|
|
103
|
+
include ActionFigure::Formatter
|
|
104
|
+
|
|
105
|
+
def Ok: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
106
|
+
def Created: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
107
|
+
def Accepted: (?resource: untyped?, ?meta: untyped?) -> ActionFigure::response
|
|
108
|
+
def UnprocessableContent: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
109
|
+
def NotFound: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
110
|
+
def Forbidden: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# JSON:API-formatted responses
|
|
114
|
+
module JsonApi
|
|
115
|
+
include ActionFigure::Formatter
|
|
116
|
+
|
|
117
|
+
def Ok: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
118
|
+
def Created: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
119
|
+
def Accepted: (?resource: untyped?, ?meta: untyped?) -> ActionFigure::response
|
|
120
|
+
def UnprocessableContent: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
121
|
+
def NotFound: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
122
|
+
def Forbidden: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
123
|
+
|
|
124
|
+
# Simple resource serialization for JSON:API
|
|
125
|
+
class Resource
|
|
126
|
+
def self.serialize: (untyped resource) -> untyped
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Uniform { data:, errors:, status: } envelope
|
|
131
|
+
module Wrapped
|
|
132
|
+
include ActionFigure::Formatter
|
|
133
|
+
|
|
134
|
+
def Ok: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
135
|
+
def Created: (resource: untyped, ?meta: untyped?) -> ActionFigure::response
|
|
136
|
+
def Accepted: (?resource: untyped?, ?meta: untyped?) -> ActionFigure::response
|
|
137
|
+
def UnprocessableContent: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
138
|
+
def NotFound: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
139
|
+
def Forbidden: (errors: ActionFigure::error_hash) -> ActionFigure::response
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
module Testing
|
|
144
|
+
# Minitest assertions for action response results
|
|
145
|
+
module Minitest
|
|
146
|
+
def assert_Ok: (ActionFigure::response result, ?String? msg) -> void
|
|
147
|
+
def assert_Created: (ActionFigure::response result, ?String? msg) -> void
|
|
148
|
+
def assert_Accepted: (ActionFigure::response result, ?String? msg) -> void
|
|
149
|
+
def assert_NoContent: (ActionFigure::response result, ?String? msg) -> void
|
|
150
|
+
def assert_UnprocessableContent: (ActionFigure::response result, ?String? msg) -> void
|
|
151
|
+
def assert_NotFound: (ActionFigure::response result, ?String? msg) -> void
|
|
152
|
+
def assert_Forbidden: (ActionFigure::response result, ?String? msg) -> void
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# RSpec custom matchers (be_Ok, be_Created, etc.)
|
|
156
|
+
module RSpec
|
|
157
|
+
MATCHERS: Hash[Symbol, Symbol]
|
|
158
|
+
end
|
|
159
|
+
end
|
|
4
160
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: action_figure
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tad Thorley
|
|
@@ -23,8 +23,8 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '1.10'
|
|
26
|
-
description: Replaces
|
|
27
|
-
|
|
26
|
+
description: Replaces service objects with explicit, purpose-driven classes for Rails
|
|
27
|
+
controller actions
|
|
28
28
|
executables: []
|
|
29
29
|
extensions: []
|
|
30
30
|
extra_rdoc_files: []
|
|
@@ -32,7 +32,27 @@ files:
|
|
|
32
32
|
- LICENSE.txt
|
|
33
33
|
- README.md
|
|
34
34
|
- Rakefile
|
|
35
|
+
- docs/actions.md
|
|
36
|
+
- docs/activesupport-notifications.md
|
|
37
|
+
- docs/configuration.md
|
|
38
|
+
- docs/custom-formatters.md
|
|
39
|
+
- docs/integration-patterns.md
|
|
40
|
+
- docs/response-formatters.md
|
|
41
|
+
- docs/status-codes.md
|
|
42
|
+
- docs/testing.md
|
|
43
|
+
- docs/validation.md
|
|
35
44
|
- lib/action_figure.rb
|
|
45
|
+
- lib/action_figure/configuration.rb
|
|
46
|
+
- lib/action_figure/core.rb
|
|
47
|
+
- lib/action_figure/format_registry.rb
|
|
48
|
+
- lib/action_figure/formatter.rb
|
|
49
|
+
- lib/action_figure/formatters/default.rb
|
|
50
|
+
- lib/action_figure/formatters/jsend.rb
|
|
51
|
+
- lib/action_figure/formatters/json_api.rb
|
|
52
|
+
- lib/action_figure/formatters/json_api/resource.rb
|
|
53
|
+
- lib/action_figure/formatters/wrapped.rb
|
|
54
|
+
- lib/action_figure/testing/minitest.rb
|
|
55
|
+
- lib/action_figure/testing/rspec.rb
|
|
36
56
|
- lib/action_figure/version.rb
|
|
37
57
|
- sig/action_figure.rbs
|
|
38
58
|
homepage: https://github.com/phaedryx/action_figure
|
|
@@ -41,6 +61,7 @@ licenses:
|
|
|
41
61
|
metadata:
|
|
42
62
|
homepage_uri: https://github.com/phaedryx/action_figure
|
|
43
63
|
source_code_uri: https://github.com/phaedryx/action_figure
|
|
64
|
+
rubygems_mfa_required: 'true'
|
|
44
65
|
rdoc_options: []
|
|
45
66
|
require_paths:
|
|
46
67
|
- lib
|
|
@@ -48,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
48
69
|
requirements:
|
|
49
70
|
- - ">="
|
|
50
71
|
- !ruby/object:Gem::Version
|
|
51
|
-
version: 3.
|
|
72
|
+
version: 3.2.0
|
|
52
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
74
|
requirements:
|
|
54
75
|
- - ">="
|
|
@@ -57,5 +78,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
57
78
|
requirements: []
|
|
58
79
|
rubygems_version: 4.0.8
|
|
59
80
|
specification_version: 4
|
|
60
|
-
summary:
|
|
81
|
+
summary: Fully-articulated controller actions
|
|
61
82
|
test_files: []
|