jsonrpc-middleware 0.4.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/.claude/commands/gemfile/update.md +52 -0
- data/.claude/settings.local.json +6 -2
- data/CHANGELOG.md +90 -1
- data/README.md +3 -0
- data/Rakefile +57 -0
- data/examples/README.md +9 -0
- data/examples/procedures.rb +1 -5
- data/examples/rack/Gemfile.lock +10 -1
- data/examples/rack-echo/Gemfile.lock +10 -1
- data/examples/rails/Gemfile.lock +10 -22
- data/examples/rails/config/initializers/jsonrpc.rb +1 -5
- data/examples/rails-routing-dsl/README.md +199 -0
- data/examples/rails-routing-dsl/config.ru +146 -0
- data/examples/rails-single-file-routing/README.md +39 -4
- data/examples/rails-single-file-routing/config.ru +18 -5
- data/examples/sinatra-classic/Gemfile.lock +3 -2
- data/examples/sinatra-modular/Gemfile.lock +3 -2
- data/lib/jsonrpc/batch_request.rb +1 -14
- data/lib/jsonrpc/batch_response.rb +1 -1
- data/lib/jsonrpc/configuration.rb +25 -3
- data/lib/jsonrpc/error.rb +1 -1
- data/lib/jsonrpc/middleware.rb +3 -2
- data/lib/jsonrpc/notification.rb +1 -1
- data/lib/jsonrpc/parser.rb +9 -7
- data/lib/jsonrpc/railtie/batch_constraint.rb +25 -0
- data/lib/jsonrpc/railtie/mapper_extension.rb +34 -0
- data/lib/jsonrpc/railtie/method_constraint.rb +1 -1
- data/lib/jsonrpc/railtie/routes_dsl.rb +147 -0
- data/lib/jsonrpc/railtie.rb +9 -2
- data/lib/jsonrpc/request.rb +12 -84
- data/lib/jsonrpc/response.rb +10 -59
- data/lib/jsonrpc/types.rb +13 -0
- data/lib/jsonrpc/version.rb +1 -1
- data/lib/jsonrpc.rb +2 -0
- metadata +38 -3
- /data/{.aiexclude → .aiignore} +0 -0
data/lib/jsonrpc/railtie.rb
CHANGED
@@ -8,6 +8,13 @@ module JSONRPC
|
|
8
8
|
app.middleware.use JSONRPC::Middleware
|
9
9
|
end
|
10
10
|
|
11
|
+
# Register the JSON-RPC routes DSL extension
|
12
|
+
initializer 'jsonrpc.routes_dsl' do
|
13
|
+
ActiveSupport.on_load(:action_controller) do
|
14
|
+
ActionDispatch::Routing::Mapper.include(JSONRPC::MapperExtension)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
11
18
|
initializer 'jsonrpc.renderer' do
|
12
19
|
ActiveSupport.on_load(:action_controller) do
|
13
20
|
Mime::Type.register 'application/json', :jsonrpc
|
@@ -28,7 +35,7 @@ module JSONRPC
|
|
28
35
|
self.response_body = ''
|
29
36
|
''
|
30
37
|
else
|
31
|
-
result_data
|
38
|
+
MultiJson.dump(result_data)
|
32
39
|
end
|
33
40
|
elsif jsonrpc_notification?
|
34
41
|
# Notification - no response body
|
@@ -37,7 +44,7 @@ module JSONRPC
|
|
37
44
|
''
|
38
45
|
else
|
39
46
|
# Fallback - treat as regular JSON-RPC response
|
40
|
-
result_data
|
47
|
+
MultiJson.dump(result_data)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
end
|
data/lib/jsonrpc/request.rb
CHANGED
@@ -13,7 +13,7 @@ module JSONRPC
|
|
13
13
|
# @example Create a request with named parameters
|
14
14
|
# request = JSONRPC::Request.new(method: "subtract", params: { minuend: 42, subtrahend: 23 }, id: 3)
|
15
15
|
#
|
16
|
-
class Request
|
16
|
+
class Request < Dry::Struct
|
17
17
|
# JSON-RPC protocol version
|
18
18
|
#
|
19
19
|
# @api public
|
@@ -23,7 +23,7 @@ module JSONRPC
|
|
23
23
|
#
|
24
24
|
# @return [String]
|
25
25
|
#
|
26
|
-
|
26
|
+
attribute :jsonrpc, Types::String.default('2.0')
|
27
27
|
|
28
28
|
# The method name to invoke
|
29
29
|
#
|
@@ -34,7 +34,7 @@ module JSONRPC
|
|
34
34
|
#
|
35
35
|
# @return [String]
|
36
36
|
#
|
37
|
-
|
37
|
+
attribute :method, Types::String.constrained(format: /\A(?!rpc\.)/)
|
38
38
|
|
39
39
|
# Parameters to pass to the method
|
40
40
|
#
|
@@ -45,7 +45,7 @@ module JSONRPC
|
|
45
45
|
#
|
46
46
|
# @return [Hash, Array, nil]
|
47
47
|
#
|
48
|
-
|
48
|
+
attribute? :params, (Types::Hash | Types::Array).optional
|
49
49
|
|
50
50
|
# The request identifier
|
51
51
|
#
|
@@ -56,36 +56,7 @@ module JSONRPC
|
|
56
56
|
#
|
57
57
|
# @return [String, Integer, nil]
|
58
58
|
#
|
59
|
-
|
60
|
-
|
61
|
-
# Creates a new JSON-RPC 2.0 Request object
|
62
|
-
#
|
63
|
-
# @api public
|
64
|
-
#
|
65
|
-
# @example Create a request with positional parameters
|
66
|
-
# JSONRPC::Request.new(method: "subtract", params: [42, 23], id: 1)
|
67
|
-
#
|
68
|
-
# @param method [String] the name of the method to be invoked
|
69
|
-
# @param params [Hash, Array, nil] the parameters to be used during method invocation
|
70
|
-
# @param id [String, Integer, nil] the request identifier
|
71
|
-
#
|
72
|
-
# @raise [ArgumentError] if method is not a String or is reserved
|
73
|
-
#
|
74
|
-
# @raise [ArgumentError] if params is not a Hash, Array, or nil
|
75
|
-
#
|
76
|
-
# @raise [ArgumentError] if id is not a String, Integer, or nil
|
77
|
-
#
|
78
|
-
def initialize(method:, id:, params: nil)
|
79
|
-
@jsonrpc = '2.0'
|
80
|
-
|
81
|
-
validate_method(method)
|
82
|
-
validate_params(params)
|
83
|
-
validate_id(id)
|
84
|
-
|
85
|
-
@method = method
|
86
|
-
@params = params
|
87
|
-
@id = id
|
88
|
-
end
|
59
|
+
attribute? :id, Types::String | Types::Integer | Types::Nil
|
89
60
|
|
90
61
|
# Converts the request to a JSON-compatible Hash
|
91
62
|
#
|
@@ -119,61 +90,18 @@ module JSONRPC
|
|
119
90
|
# @return [String] the request as a JSON string
|
120
91
|
#
|
121
92
|
def to_json(*)
|
122
|
-
|
93
|
+
MultiJson.dump(to_h, *)
|
123
94
|
end
|
124
95
|
|
125
|
-
|
126
|
-
|
127
|
-
# Validates that the method name meets JSON-RPC 2.0 requirements
|
128
|
-
#
|
129
|
-
# @api private
|
130
|
-
#
|
131
|
-
# @param method [String] the method name
|
132
|
-
#
|
133
|
-
# @raise [ArgumentError] if method is not a String or is reserved
|
134
|
-
#
|
135
|
-
# @return [void]
|
136
|
-
#
|
137
|
-
def validate_method(method)
|
138
|
-
raise ArgumentError, 'Method must be a String' unless method.is_a?(String)
|
139
|
-
|
140
|
-
return unless method.start_with?('rpc.')
|
141
|
-
|
142
|
-
raise ArgumentError, "Method names starting with 'rpc.' are reserved"
|
143
|
-
end
|
144
|
-
|
145
|
-
# Validates that the params is a valid structure according to JSON-RPC 2.0
|
146
|
-
#
|
147
|
-
# @api private
|
148
|
-
#
|
149
|
-
# @param params [Hash, Array, nil] the parameters
|
150
|
-
#
|
151
|
-
# @raise [ArgumentError] if params is not a Hash, Array, or nil
|
152
|
-
#
|
153
|
-
# @return [void]
|
154
|
-
#
|
155
|
-
def validate_params(params)
|
156
|
-
return if params.nil?
|
157
|
-
|
158
|
-
return if params.is_a?(Hash) || params.is_a?(Array)
|
159
|
-
|
160
|
-
raise ArgumentError, 'Params must be an Object, Array, or omitted'
|
161
|
-
end
|
162
|
-
|
163
|
-
# Validates that the id meets JSON-RPC 2.0 requirements
|
164
|
-
#
|
165
|
-
# @api private
|
96
|
+
# The method name to invoke
|
166
97
|
#
|
167
|
-
# @
|
98
|
+
# @api public
|
168
99
|
#
|
169
|
-
# @
|
100
|
+
# @example
|
101
|
+
# request.method # => "subtract"
|
170
102
|
#
|
171
|
-
# @return [
|
103
|
+
# @return [String]
|
172
104
|
#
|
173
|
-
def
|
174
|
-
return if id.nil?
|
175
|
-
|
176
|
-
raise ArgumentError, 'ID must be a String, Integer, or nil' unless id.is_a?(String) || id.is_a?(Integer)
|
177
|
-
end
|
105
|
+
def method = attributes[:method]
|
178
106
|
end
|
179
107
|
end
|
data/lib/jsonrpc/response.rb
CHANGED
@@ -19,7 +19,9 @@ module JSONRPC
|
|
19
19
|
# error = JSONRPC::Error.new(code: -32601, message: "Method not found")
|
20
20
|
# response = JSONRPC::Response.new(error: error, id: 1)
|
21
21
|
#
|
22
|
-
class Response
|
22
|
+
class Response < Dry::Struct
|
23
|
+
transform_keys(&:to_sym)
|
24
|
+
|
23
25
|
# JSON-RPC protocol version
|
24
26
|
#
|
25
27
|
# @api public
|
@@ -29,7 +31,7 @@ module JSONRPC
|
|
29
31
|
#
|
30
32
|
# @return [String]
|
31
33
|
#
|
32
|
-
|
34
|
+
attribute :jsonrpc, Types::String.default('2.0')
|
33
35
|
|
34
36
|
# The result of the method invocation (for success)
|
35
37
|
#
|
@@ -40,7 +42,7 @@ module JSONRPC
|
|
40
42
|
#
|
41
43
|
# @return [Object, nil]
|
42
44
|
#
|
43
|
-
|
45
|
+
attribute? :result, Types::Any
|
44
46
|
|
45
47
|
# The error object (for failure)
|
46
48
|
#
|
@@ -51,7 +53,7 @@ module JSONRPC
|
|
51
53
|
#
|
52
54
|
# @return [JSONRPC::Error, nil]
|
53
55
|
#
|
54
|
-
|
56
|
+
attribute? :error, Types.Instance(JSONRPC::Error).optional
|
55
57
|
|
56
58
|
# The request identifier
|
57
59
|
#
|
@@ -62,7 +64,7 @@ module JSONRPC
|
|
62
64
|
#
|
63
65
|
# @return [String, Integer, nil]
|
64
66
|
#
|
65
|
-
|
67
|
+
attribute? :id, Types::String | Types::Integer | Types::Nil
|
66
68
|
|
67
69
|
# Creates a new JSON-RPC 2.0 Response object
|
68
70
|
#
|
@@ -85,16 +87,6 @@ module JSONRPC
|
|
85
87
|
#
|
86
88
|
# @raise [ArgumentError] if id is not a String, Integer, or nil
|
87
89
|
#
|
88
|
-
def initialize(id:, result: nil, error: nil)
|
89
|
-
@jsonrpc = '2.0'
|
90
|
-
|
91
|
-
validate_result_and_error(result, error)
|
92
|
-
validate_id(id)
|
93
|
-
|
94
|
-
@result = result
|
95
|
-
@error = error
|
96
|
-
@id = id
|
97
|
-
end
|
98
90
|
|
99
91
|
# Checks if the response is successful
|
100
92
|
#
|
@@ -106,7 +98,7 @@ module JSONRPC
|
|
106
98
|
# @return [Boolean] true if the response contains a result, false if it contains an error
|
107
99
|
#
|
108
100
|
def success?
|
109
|
-
|
101
|
+
!result.nil?
|
110
102
|
end
|
111
103
|
|
112
104
|
# Checks if the response is an error
|
@@ -119,7 +111,7 @@ module JSONRPC
|
|
119
111
|
# @return [Boolean] true if the response contains an error, false if it contains a result
|
120
112
|
#
|
121
113
|
def error?
|
122
|
-
|
114
|
+
!error.nil?
|
123
115
|
end
|
124
116
|
|
125
117
|
# Converts the response to a JSON-compatible Hash
|
@@ -156,48 +148,7 @@ module JSONRPC
|
|
156
148
|
# @return [String] the response as a JSON string
|
157
149
|
#
|
158
150
|
def to_json(*)
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
private
|
163
|
-
|
164
|
-
# Validates that exactly one of result or error is present
|
165
|
-
#
|
166
|
-
# @api private
|
167
|
-
#
|
168
|
-
# @param result [Object, nil] the result
|
169
|
-
# @param error [JSONRPC::Error, nil] the error
|
170
|
-
#
|
171
|
-
# @raise [ArgumentError] if both result and error are present or both are nil
|
172
|
-
#
|
173
|
-
# @raise [ArgumentError] if error is present but not a JSONRPC::Error
|
174
|
-
#
|
175
|
-
# @return [void]
|
176
|
-
#
|
177
|
-
def validate_result_and_error(result, error)
|
178
|
-
raise ArgumentError, 'Either result or error must be present' if result.nil? && error.nil?
|
179
|
-
|
180
|
-
raise ArgumentError, 'Response cannot contain both result and error' if !result.nil? && !error.nil?
|
181
|
-
|
182
|
-
return unless !error.nil? && !error.is_a?(Error)
|
183
|
-
|
184
|
-
raise ArgumentError, 'Error must be a JSONRPC::Error'
|
185
|
-
end
|
186
|
-
|
187
|
-
# Validates that the id meets JSON-RPC 2.0 requirements
|
188
|
-
#
|
189
|
-
# @api private
|
190
|
-
#
|
191
|
-
# @param id [String, Integer, nil] the request identifier
|
192
|
-
#
|
193
|
-
# @raise [ArgumentError] if id is not a String, Integer, or nil
|
194
|
-
#
|
195
|
-
# @return [void]
|
196
|
-
#
|
197
|
-
def validate_id(id)
|
198
|
-
return if id.nil?
|
199
|
-
|
200
|
-
raise ArgumentError, 'ID must be a String, Integer, or nil' unless id.is_a?(String) || id.is_a?(Integer)
|
151
|
+
MultiJson.dump(to_h, *)
|
201
152
|
end
|
202
153
|
end
|
203
154
|
end
|
data/lib/jsonrpc/version.rb
CHANGED
data/lib/jsonrpc.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonrpc-middleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wilson Silva
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: dry-struct
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.8'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.8'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: dry-validation
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -23,6 +37,20 @@ dependencies:
|
|
23
37
|
- - "~>"
|
24
38
|
- !ruby/object:Gem::Version
|
25
39
|
version: '1.11'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: multi_json
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.17'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.17'
|
26
54
|
- !ruby/object:Gem::Dependency
|
27
55
|
name: zeitwerk
|
28
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,8 +73,9 @@ executables: []
|
|
45
73
|
extensions: []
|
46
74
|
extra_rdoc_files: []
|
47
75
|
files:
|
48
|
-
- ".
|
76
|
+
- ".aiignore"
|
49
77
|
- ".claude/commands/document.md"
|
78
|
+
- ".claude/commands/gemfile/update.md"
|
50
79
|
- ".claude/commands/test.md"
|
51
80
|
- ".claude/docs/yard.md"
|
52
81
|
- ".claude/settings.local.json"
|
@@ -80,6 +109,8 @@ files:
|
|
80
109
|
- examples/rack/README.md
|
81
110
|
- examples/rack/app.rb
|
82
111
|
- examples/rack/config.ru
|
112
|
+
- examples/rails-routing-dsl/README.md
|
113
|
+
- examples/rails-routing-dsl/config.ru
|
83
114
|
- examples/rails-single-file-routing/README.md
|
84
115
|
- examples/rails-single-file-routing/config.ru
|
85
116
|
- examples/rails-single-file/README.md
|
@@ -136,9 +167,13 @@ files:
|
|
136
167
|
- lib/jsonrpc/notification.rb
|
137
168
|
- lib/jsonrpc/parser.rb
|
138
169
|
- lib/jsonrpc/railtie.rb
|
170
|
+
- lib/jsonrpc/railtie/batch_constraint.rb
|
171
|
+
- lib/jsonrpc/railtie/mapper_extension.rb
|
139
172
|
- lib/jsonrpc/railtie/method_constraint.rb
|
173
|
+
- lib/jsonrpc/railtie/routes_dsl.rb
|
140
174
|
- lib/jsonrpc/request.rb
|
141
175
|
- lib/jsonrpc/response.rb
|
176
|
+
- lib/jsonrpc/types.rb
|
142
177
|
- lib/jsonrpc/validator.rb
|
143
178
|
- lib/jsonrpc/version.rb
|
144
179
|
- sig/jsonrpc.rbs
|
@@ -166,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
201
|
- !ruby/object:Gem::Version
|
167
202
|
version: '0'
|
168
203
|
requirements: []
|
169
|
-
rubygems_version: 3.7.
|
204
|
+
rubygems_version: 3.7.2
|
170
205
|
specification_version: 4
|
171
206
|
summary: Rack middleware implementing the JSON-RPC 2.0 protocol.
|
172
207
|
test_files: []
|
/data/{.aiexclude → .aiignore}
RENAMED
File without changes
|