jsonrpc_interface 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4a8bb604718da7dc4c8a9277737d334e61ce4cac8854102b863679e1c78d5f6
4
- data.tar.gz: 9a3865cd9a55bf84528d8c3a3155a949d5c75c1a46a8df26fa56fa6c63dc5aab
3
+ metadata.gz: 25256ea9e6e7e75cb545b1d76c443678e06a4a7e94f055c0288abd3a368dde63
4
+ data.tar.gz: 3984365f41a8f2629011e9144df1c3f2ec421fa02f9e582517db74a5bb95f404
5
5
  SHA512:
6
- metadata.gz: 9af958fa2a646589d9503b23d50c787366b6a40717ebe61cabbc6334cbf96d03f28deb8c9ab9c3ac4c883f6072f3ba4a61c28576adf9fa8b125040104950ddf0
7
- data.tar.gz: 7cb788b359de7b8433172db8f9f2d8ea9f7f4a47cf640f05446ceda363d50cbbbb01d0c861eb1910a10e3cf1854c5ad4d07bd5279763caefa553d48e5dd66028
6
+ metadata.gz: eb0dde16f67f210bd10fe6c226c8cf9e421d5a12a5b5c894ac8e2687d8aa8f26375c675dfd000b7df12304e762c6e04f534dd8cc6b9ad547a3ee6b7787c18d28
7
+ data.tar.gz: a92f486f02ac219400b4b6aa083fd7c7e09ec4057645b8f0eaa98bb60bbab63d4172f2c71d7c1b369106459332053772b311ed7a7d6e1ddeb743d8077130e70b
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  .rspec_status
10
10
  .ruby-version
11
11
  *.gem
12
+ /.gem_rbs_collection/
data/.rubocop.yml CHANGED
@@ -12,5 +12,10 @@ AllCops:
12
12
  - spec/**/*.rb
13
13
  - Gemfile
14
14
  - Rakefile
15
+ - Steepfile
15
16
  - jsonrpc_interface.gemspec
16
17
  - bin/console
18
+
19
+ Rake/Desc:
20
+ Exclude:
21
+ - Rakefile
data/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  ## [Unreleased]
5
5
 
6
- ## [0.0.1] - 2023-05-028
6
+ ## [0.1.0] - 2023-06-25
7
+
8
+ - Release;
9
+
10
+ ## [0.0.1] - 2023-05-28
7
11
 
8
12
  - Placement of the gem on RubyGems.org;
data/Gemfile.lock CHANGED
@@ -2,6 +2,9 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  jsonrpc_interface (0.1.0)
5
+ smart_schema (~> 0.11)
6
+ smart_types (~> 0.8)
7
+ smart_value-object (~> 0.2)
5
8
 
6
9
  GEM
7
10
  remote: https://rubygems.org/
@@ -22,23 +25,38 @@ GEM
22
25
  ast (2.4.2)
23
26
  coderay (1.1.3)
24
27
  concurrent-ruby (1.2.2)
28
+ csv (3.2.6)
25
29
  diff-lcs (1.5.0)
26
30
  docile (1.4.0)
27
- i18n (1.13.0)
31
+ ffi (1.15.5)
32
+ fileutils (1.7.1)
33
+ i18n (1.14.1)
28
34
  concurrent-ruby (~> 1.0)
29
35
  json (2.6.3)
36
+ language_server-protocol (3.17.0.3)
37
+ listen (3.8.0)
38
+ rb-fsevent (~> 0.10, >= 0.10.3)
39
+ rb-inotify (~> 0.9, >= 0.9.10)
40
+ logger (1.5.3)
30
41
  method_source (1.0.0)
31
42
  minitest (5.18.0)
32
43
  parallel (1.23.0)
33
- parser (3.2.2.1)
44
+ parser (3.2.2.3)
34
45
  ast (~> 2.4.1)
46
+ racc
35
47
  pry (0.14.2)
36
48
  coderay (~> 1.1)
37
49
  method_source (~> 1.0)
50
+ qonfig (0.28.0)
51
+ racc (1.7.0)
38
52
  rack (3.0.7)
39
53
  rainbow (3.1.1)
40
54
  rake (13.0.6)
41
- regexp_parser (2.8.0)
55
+ rb-fsevent (0.11.2)
56
+ rb-inotify (0.10.1)
57
+ ffi (~> 1.0)
58
+ rbs (3.1.0)
59
+ regexp_parser (2.8.1)
42
60
  rexml (3.2.5)
43
61
  rspec (3.12.0)
44
62
  rspec-core (~> 3.12.0)
@@ -63,7 +81,7 @@ GEM
63
81
  rubocop-ast (>= 1.28.0, < 2.0)
64
82
  ruby-progressbar (~> 1.7)
65
83
  unicode-display_width (>= 2.4.0, < 3.0)
66
- rubocop-ast (1.28.1)
84
+ rubocop-ast (1.29.0)
67
85
  parser (>= 3.2.1.0)
68
86
  rubocop-capybara (2.18.0)
69
87
  rubocop (~> 1.41)
@@ -83,12 +101,43 @@ GEM
83
101
  rubocop-capybara (~> 2.17)
84
102
  rubocop-factory_bot (~> 2.22)
85
103
  ruby-progressbar (1.13.0)
104
+ securerandom (0.2.2)
86
105
  simplecov (0.22.0)
87
106
  docile (~> 1.1)
88
107
  simplecov-html (~> 0.11)
89
108
  simplecov_json_formatter (~> 0.1)
90
109
  simplecov-html (0.12.3)
91
110
  simplecov_json_formatter (0.1.4)
111
+ smart_engine (0.17.0)
112
+ smart_initializer (0.11.1)
113
+ qonfig (~> 0.24)
114
+ smart_engine (~> 0.16)
115
+ smart_types (~> 0.8)
116
+ smart_schema (0.11.0)
117
+ smart_engine (~> 0.17)
118
+ smart_types (~> 0.8)
119
+ smart_types (0.8.0)
120
+ smart_engine (~> 0.11)
121
+ smart_value-object (0.2.0)
122
+ smart_initializer (~> 0.5)
123
+ steep (1.4.0)
124
+ activesupport (>= 5.1)
125
+ concurrent-ruby (>= 1.2.2)
126
+ csv (>= 3.0.9)
127
+ fileutils (>= 1.1.0)
128
+ json (>= 2.1.0)
129
+ language_server-protocol (>= 3.15, < 4.0)
130
+ listen (~> 3.0)
131
+ logger (>= 1.3.0)
132
+ parser (>= 3.1)
133
+ rainbow (>= 2.2.2, < 4.0)
134
+ rbs (>= 2.8.0)
135
+ securerandom (>= 0.1)
136
+ strscan (>= 1.0.0)
137
+ terminal-table (>= 2, < 4)
138
+ strscan (3.0.6)
139
+ terminal-table (3.0.2)
140
+ unicode-display_width (>= 1.1.1, < 3)
92
141
  tzinfo (2.0.6)
93
142
  concurrent-ruby (~> 1.0)
94
143
  unicode-display_width (2.4.2)
@@ -102,8 +151,10 @@ DEPENDENCIES
102
151
  jsonrpc_interface!
103
152
  pry (~> 0.14)
104
153
  rake (~> 13.0)
154
+ rbs (~> 3.1)
105
155
  rspec (~> 3.12)
106
156
  simplecov (~> 0.22)
157
+ steep (~> 1.4)
107
158
 
108
159
  BUNDLED WITH
109
160
  2.4.13
data/README.md CHANGED
@@ -1 +1,328 @@
1
1
  # JSONRPC Interface
2
+
3
+ JRPC Request, JRPC Notification, JRPC Response, JRPC Error Response, JRPC Object Builder and JRPC Error Codes in Object Oriented Way.
4
+
5
+ ---
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Development](#development)
10
+ - [License](#license)
11
+ - [Authors](#authors)
12
+
13
+ ## Installation
14
+
15
+ ```ruby
16
+ gem 'jsonrpc_interface'
17
+ ```
18
+
19
+ ```shell
20
+ bundle install
21
+ # --- or ---
22
+ gem install jsonrpc_interface
23
+ ```
24
+
25
+ ```ruby
26
+ require 'jsonrpc_interface'
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ - [JSONRPC::ERRORS](#jsonrpcerrors)
32
+ - [JSONRPC::Request](#jsonrpcrequest)
33
+ - [Schema](#jsonrpcrequestschema)
34
+ - [JSONRPC::Notification](#jsonrpcnotification)
35
+ - [Schema](#jsonrpcnotificationschema)
36
+ - [JSONRPC::Response](#jsonrpcresponse)
37
+ - [JSONRPC::ErrorResponse](#jsonrpcerrorresponse)
38
+ - [Schema](#jsonrpcerrorresponseschema)
39
+ - [JSONRPC::RPCObject](#jsonrpcrpcobject)
40
+ - [.response](#response)
41
+ - [.request](#request)
42
+ - [.notification](#notification)
43
+ - [.invalid_request_error](#invalid_request_error)
44
+ - [.parse_error](#parse_error)
45
+ - [.jsonrpc_specification_violation_error](#jsonrpc_specification_violation_error)
46
+ - [.method_not_found_error](#method_not_found_error)
47
+ - [.invalid_params_error](#invalid_params_error)
48
+ - [.internal_error](#internal_error)
49
+ - [.detailed_internal_error](#detailed_internal_error)
50
+
51
+ ---
52
+
53
+ ### JSONRPC::ERRORS
54
+
55
+ ```ruby
56
+ JSONRPC::ERRORS
57
+ # =>
58
+ {
59
+ parse_error: { code: -32_700, message: 'Parse Error' },
60
+ invalid_request: { code: -32_600, message: 'Invalid Request' },
61
+ method_not_found: { code: -32_601, message: 'Method Not Found' },
62
+ invalid_params: { code: -32_602, message: 'Invalid Params' },
63
+ internal_error: { code: -32_603, message: 'Internal Error' },
64
+ unauthorized: { code: -33_001, message: 'Unauthorized' },
65
+ application_error: { code: -33_002, message: 'Application Error' },
66
+ jsonrpc_specification_violation: { code: -33_003, message: 'JSONRPC Specification Violation' }
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ### JSONRPC::Request
73
+
74
+ ```ruby
75
+ JSONRPC::Request
76
+ JSONRPC::Request.new(jsonrpc: '2.0', method: 'some.method', params: { some: 'params' }, id: 'sOmEiD')
77
+ JSONRPC::Request#jsonrpc (String)
78
+ JSONRPC::Request#method (String)
79
+ JSONRPC::Request#params (Hash)
80
+ JSONRPC::Request#id (String)
81
+ ```
82
+
83
+ ### JSONRPC::Request::Schema
84
+
85
+ ```ruby
86
+ schema do
87
+ required(:jsonrpc).type(:string).filled
88
+ required(:method).type(:string).filled
89
+ required(:params).type(:hash).filled
90
+ required(:id).type(:string).filled
91
+ end
92
+ ```
93
+
94
+ ---
95
+
96
+ ### JSONRPC::Notification
97
+
98
+ ```ruby
99
+ JSONRPC::Notification
100
+ JSONRPC::Notification.new(jsonrpc: '2.0', method: 'some.method', params: { some: 'params' })
101
+ JSONRPC::Notification#jsonrpc (String)
102
+ JSONRPC::Notification#method (String)
103
+ JSONRPC::Notification#params (Hash)
104
+ ```
105
+
106
+ ### JSONRPC::Notification::Schema
107
+
108
+ ```ruby
109
+ schema do
110
+ required(:jsonrpc).type(:string).filled
111
+ required(:method).type(:string).filled
112
+ required(:params).type(:hash).filled
113
+ end
114
+ ```
115
+
116
+ ---
117
+
118
+ ### JSONRPC::Response
119
+
120
+ ```ruby
121
+ JSONRPC::Response
122
+ JSONRPC::Response.new(jsonrpc: '2.0', result: { some: 'result' }, id: 'sOmEiD')
123
+ JSONRPC::Response#jsonrpc (String)
124
+ JSONRPC::Response#result (Hash)
125
+ JSONRPC::Response#id (String)
126
+ ```
127
+
128
+ ---
129
+
130
+ ### JSONRPC::ErrorResponse
131
+
132
+ ```ruby
133
+ JSONRPC::ErrorResponse
134
+ JSONRPC::ErrorResponse.new(jsonrpc: '2.0', method: 'some.method', params: { some: 'params' }, id: nil)
135
+ JSONRPC::ErrorResponse.new(jsonrpc: '2.0', method: 'some.method', params: { some: 'params' }, id: 'sOmEiD')
136
+ JSONRPC::ErrorResponse#jsonrpc (String)
137
+ JSONRPC::ErrorResponse#error (Hash)
138
+ JSONRPC::ErrorResponse#id (String, NilClass)
139
+
140
+ JSONRPC::ErrorResponse#error
141
+ # signature =>
142
+ { code: Integer, message: String, data: Hash }
143
+ ```
144
+
145
+ ### JSONRPC::ErrorResponse::Schema
146
+
147
+ ```ruby
148
+ schema do
149
+ required(:code).type(:integer).filled
150
+ required(:message).type(:string).filled
151
+ required(:data).type(:hash).filled
152
+ end
153
+ ```
154
+
155
+ ---
156
+
157
+ ### JSONRPC::RPCObject
158
+
159
+ - [.response](#response)
160
+ - [.request](#request)
161
+ - [.notification](#notification)
162
+ - [.invalid_request_error](#invalid_request_error)
163
+ - [.parse_error](#parse_error)
164
+ - [.jsonrpc_specification_violation_error](#jsonrpc_specification_violation_error)
165
+ - [.method_not_found_error](#method_not_found_error)
166
+ - [.invalid_params_error](#invalid_params_error)
167
+ - [.internal_error](#internal_error)
168
+ - [.detailed_internal_error](#detailed_internal_error)
169
+
170
+ ### .response
171
+
172
+ ```ruby
173
+ JSONRPC::RPCObject.response(
174
+ { some: 'data' },
175
+ request_id: SecureRandom.uuid
176
+ ) # => JSONRPC::Response
177
+ ```
178
+
179
+ ### .request
180
+
181
+
182
+ ```ruby
183
+ JSONRPC::RPCObject.request(
184
+ method: 'some.method',
185
+ params: { some: 'params' },
186
+ request_id: SecureRandom.uuid
187
+ ) # => JSONRPC::Request
188
+ ```
189
+
190
+ ### .notification
191
+
192
+ ```ruby
193
+ JSONRPC::RPCObject.notification(
194
+ method: 'some.method',
195
+ params: { some: 'params' }
196
+ ) # => JSONRPC::Notification
197
+ ```
198
+
199
+ ### .invalid_request_error
200
+
201
+ ```ruby
202
+ JSONRPC::RPCObject.invalid_request_error({ some: 'data' })
203
+ JSONRPC::RPCObject.invalid_request_error({ some: 'data' }, request_id: SecureRandom.uuid)
204
+
205
+ JSONRPC::ErrorResponse#error
206
+ # error hash signature =>
207
+ { code: -32_600, message: 'Invalid Request', data: { some: 'data' } }
208
+ ```
209
+
210
+ ### .parse_error
211
+
212
+ ```ruby
213
+ JSONRPC::RPCObject.parse_error
214
+
215
+ JSONRPC::ErrorResponse#error
216
+ # error hash signature =>
217
+ { code: -32_700, message: 'Parse Error', data: {} }
218
+ ```
219
+
220
+ ### .jsonrpc_specification_violation_error
221
+
222
+ ```ruby
223
+ JSONRPC::RPCObject.jsonrpc_specification_violation_error
224
+ JSONRPC::RPCObject.jsonrpc_specification_violation_error(request_id: SecureRandom.uuid)
225
+
226
+ JSONRPC::ErrorResponse#error
227
+ # error hash signature =>
228
+ { code: -33_003, message: 'JSONRPC Specification Violation', data: {} }
229
+ ```
230
+
231
+ ### .method_not_found_error
232
+
233
+ ```ruby
234
+ JSONRPC::RPCObject.method_not_found_error
235
+ JSONRPC::RPCObject.method_not_found_error(request_id: SecureRandom.uuid)
236
+
237
+ JSONRPC::ErrorResponse#error
238
+ # error hash signature =>
239
+ { code: -32_601, message: 'Method Not Found', data: {} }
240
+ ```
241
+
242
+ ### .invalid_params_error
243
+
244
+ ```ruby
245
+ JSONRPC::RPCObject.invalid_params_error
246
+ JSONRPC::RPCObject.invalid_params_error(request_id: SecureRandom.uuid)
247
+
248
+ JSONRPC::ErrorResponse#error
249
+ # error hash signature =>
250
+ { code: -32_602, message: 'Invalid Params', data: {} }
251
+ ```
252
+
253
+ ### .internal_error
254
+
255
+ ```ruby
256
+ JSONRPC::RPCObject.internal_error('some', 'error', 'code', error_context: { some: 'context' })
257
+ JSONRPC::RPCObject.internal_error('some', 'error', 'code', error_context: { some: 'context' }, request_id: SecureRandom.uuid)
258
+ JSONRPC::RPCObject.internal_error
259
+ JSONRPC::RPCObject.internal_error(request_id: SecureRandom.uuid)
260
+
261
+ JSONRPC::ErrorResponse#error
262
+ # error hash signature =>
263
+ {
264
+ code: -32_603,
265
+ message: 'Internal Error',
266
+ data: {
267
+ error_codes: ['some', 'error', 'code'],
268
+ error_cotnext: { some: 'context' }
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### .detailed_internal_error
274
+
275
+ ```ruby
276
+ JSONRPC::RPCObject.detailed_internal_error(exception)
277
+ JSONRPC::RPCObject.detailed_internal_error(exception, request_id: SecureRandom.uuid)
278
+
279
+ JSONRPC::ErrorResponse#error
280
+ # signature =>
281
+ {
282
+ code: -32_603,
283
+ message: 'Internal Error',
284
+ data: {
285
+ error_codes: [],
286
+ error_cotnext: {
287
+ error_class: # => exception.class,
288
+ error_message: # => exception.message,
289
+ error_backtrace: # => exception.backtrace,
290
+ error_object: # => exception
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ ## Development
297
+
298
+ - full build (`steep` => `rubocop` => `rspec`)
299
+
300
+ ```shell
301
+ bundle exec rake
302
+ ```
303
+
304
+ - code style check (`rubocop`):
305
+
306
+ ```shell
307
+ bundle exec rake rubocop
308
+ ```
309
+
310
+ - type validation check (`steep`):
311
+
312
+ ```shell
313
+ bundle exec rake steep
314
+ ```
315
+
316
+ - tests (`rspec`):
317
+
318
+ ```shell
319
+ bundle exec rake rspec
320
+ ```
321
+
322
+ ## License
323
+
324
+ Released under MIT License.
325
+
326
+ ## Authors
327
+
328
+ [Rustam Ibragimov](https://github.com/0exp)
data/Rakefile CHANGED
@@ -7,6 +7,8 @@ require 'rubocop/rake_task'
7
7
  require 'rubocop-performance'
8
8
  require 'rubocop-rspec'
9
9
  require 'rubocop-rake'
10
+ require 'steep'
11
+ require 'steep/cli'
10
12
 
11
13
  RuboCop::RakeTask.new(:rubocop) do |t|
12
14
  config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
@@ -18,4 +20,8 @@ end
18
20
 
19
21
  RSpec::Core::RakeTask.new(:rspec)
20
22
 
21
- task default: :rspec
23
+ task :steep do
24
+ Steep::CLI.new(argv: ['check'], stdout: STDOUT, stderr: STDERR, stdin: STDIN).run
25
+ end
26
+
27
+ task default: %w[steep rubocop rspec]
data/Steepfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ target :lib do
4
+ signature 'sig'
5
+ check 'lib'
6
+ configure_code_diagnostics(Steep::Diagnostic::Ruby.strict)
7
+ end
@@ -11,7 +11,10 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['iamdaiver@gmail.com']
12
12
 
13
13
  spec.summary = 'JSONRPC Interface for Ruby projects.'
14
- spec.description = 'JSONRPC Interface for Ruby projects realised in object oriented way.'
14
+ spec.description = 'JSONRPC Interface for Ruby projects realised in object oriented way. ' \
15
+ 'JRPC Request, JRPC Notification, JRPC Response, JRPC Error Response, ' \
16
+ 'JRPC Object Builder and JRPC Error Codes.'
17
+
15
18
  spec.homepage = 'https://github.com/0exp/jsonrpc_interface'
16
19
  spec.license = 'MIT'
17
20
 
@@ -27,10 +30,16 @@ Gem::Specification.new do |spec|
27
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
31
  spec.require_paths = ['lib']
29
32
 
33
+ spec.add_dependency 'smart_schema', '~> 0.11'
34
+ spec.add_dependency 'smart_types', '~> 0.8'
35
+ spec.add_dependency 'smart_value-object', '~> 0.2'
36
+
30
37
  spec.add_development_dependency 'bundler', '~> 2.4'
31
38
  spec.add_development_dependency 'rake', '~> 13.0'
32
39
  spec.add_development_dependency 'rspec', '~> 3.12'
33
40
  spec.add_development_dependency 'armitage-rubocop', '~> 1.51'
34
41
  spec.add_development_dependency 'simplecov', '~> 0.22'
35
42
  spec.add_development_dependency 'pry', '~> 0.14'
43
+ spec.add_development_dependency 'steep', '~> 1.4'
44
+ spec.add_development_dependency 'rbs', '~> 3.1'
36
45
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ class JSONRPC::ErrorResponse < SmartCore::ValueObject
6
+ # @return [SmartCore::Schema]
7
+ #
8
+ # @api public
9
+ # @since 0.1.0
10
+ ErrorSchema = Class.new(SmartCore::Schema) do
11
+ schema do
12
+ required(:code).type(:integer).filled
13
+ required(:message).type(:string).filled
14
+ required(:data).type(:hash).filled
15
+ end
16
+ end.new
17
+
18
+ # @api public
19
+ # @since 0.1.0
20
+ SmartCore::Types::Value.define_type(:JSONRPCErrorSchema) do |type|
21
+ type.define_checker { |value| ErrorSchema.valid?(value) }
22
+ end
23
+
24
+ # @api public
25
+ # @since 0.1.0
26
+ property :jsonrpc, SmartCore::Types::Variadic::Enum('2.0')
27
+
28
+ # @api public
29
+ # @since 0.1.0
30
+ property :error, SmartCore::Types::Value::JSONRPCErrorSchema
31
+
32
+ # @api public
33
+ # @since 0.1.0
34
+ property :id, SmartCore::Types::Value::String.nilable
35
+
36
+ # @return [Boolean]
37
+ #
38
+ # @api public
39
+ # @since 0.1.0
40
+ def error? = true
41
+
42
+ # @return [Boolean]
43
+ #
44
+ # @api public
45
+ # @since 0.1.0
46
+ def success? = false
47
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ class JSONRPC::Notification < SmartCore::ValueObject
6
+ # @return [SmartCore::Schema]
7
+ #
8
+ # @api public
9
+ # @since 0.1.0
10
+ Schema = Class.new(SmartCore::Schema) do
11
+ schema do
12
+ required(:jsonrpc).type(:string).filled
13
+ required(:method).type(:string).filled
14
+ required(:params).type(:hash).filled
15
+ end
16
+ end.new
17
+
18
+ # @api public
19
+ # @since 0.1.0
20
+ property :jsonrpc, SmartCore::Types::Variadic::Enum('2.0')
21
+
22
+ # @api public
23
+ # @since 0.1.0
24
+ property :method, SmartCore::Types::Value::String
25
+
26
+ # @api public
27
+ # @since 0.1.0
28
+ property :params, SmartCore::Types::Value::Hash
29
+
30
+ # @return [Boolean]
31
+ #
32
+ # @api public
33
+ # @since 0.1.0
34
+ def notification? = true
35
+
36
+ # @return [Boolean]
37
+ #
38
+ # @api public
39
+ # @since 0.1.0
40
+ def request? = false
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ class JSONRPC::Request < SmartCore::ValueObject
6
+ # @return [SmartCore::Schema]
7
+ #
8
+ # @api public
9
+ # @since 0.1.0
10
+ Schema = Class.new(SmartCore::Schema) do
11
+ schema do
12
+ required(:jsonrpc).type(:string).filled
13
+ required(:method).type(:string).filled
14
+ required(:params).type(:hash).filled
15
+ required(:id).type(:string).filled
16
+ end
17
+ end.new
18
+
19
+ # @api public
20
+ # @since 0.1.0
21
+ property :jsonrpc, SmartCore::Types::Variadic::Enum('2.0')
22
+
23
+ # @api public
24
+ # @since 0.1.0
25
+ property :method, SmartCore::Types::Value::String
26
+
27
+ # @api public
28
+ # @since 0.1.0
29
+ property :params, SmartCore::Types::Value::Hash
30
+
31
+ # @api public
32
+ # @since 0.1.0
33
+ property :id, SmartCore::Types::Value::String
34
+
35
+ # @return [Boolean]
36
+ #
37
+ # @api public
38
+ # @since 0.1.0
39
+ def notification? = false
40
+
41
+ # @return [Boolean]
42
+ #
43
+ # @api public
44
+ # @since 0.1.0
45
+ def request? = true
46
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ class JSONRPC::Response < SmartCore::ValueObject
6
+ # @api public
7
+ # @since 0.1.0
8
+ property :jsonrpc, SmartCore::Types::Variadic::Enum('2.0')
9
+
10
+ # @api public
11
+ # @since 0.1.0
12
+ property :result, SmartCore::Types::Value::Hash
13
+
14
+ # @api public
15
+ # @since 0.1.0
16
+ property :id, SmartCore::Types::Value::String
17
+
18
+ # @return [Boolean]
19
+ #
20
+ # @api public
21
+ # @since 0.1.0
22
+ def error? = false
23
+
24
+ # @return [Boolean]
25
+ #
26
+ # @api public
27
+ # @since 0.1.0
28
+ def success? = true
29
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ module JSONRPC::RPCObject
6
+ module_function
7
+
8
+ # @param result [Hash<String|Symbol,Any>]
9
+ # @option request_id [String, NilClass]
10
+ # @return [JSONRPC::Response, NilClass]
11
+ #
12
+ # @api public
13
+ # @since 0.1.0
14
+ def response(result = {}, request_id: nil)
15
+ return if request_id == nil # NOTE: nil is treated as no result
16
+
17
+ # @type var request_id: untyped
18
+ JSONRPC::Response.new(jsonrpc: '2.0', result:, id: request_id)
19
+ end
20
+
21
+ # @param data [Hash<String|Symbol,Any>]
22
+ # @option code [Integer]
23
+ # @option message [String]
24
+ # @option request_id [String, NilClass]
25
+ # @return [JSONRPC::ErrorResponse]
26
+ #
27
+ # @api public
28
+ # @since 0.1.0
29
+ def error(
30
+ data = {},
31
+ code: JSONRPC::ERRORS[:application_error][:code],
32
+ message: JSONRPC::ERRORS[:application_error][:message],
33
+ request_id: nil
34
+ )
35
+ JSONRPC::ErrorResponse.new(
36
+ jsonrpc: '2.0',
37
+ error: { code:, message:, data: },
38
+ id: request_id
39
+ )
40
+ end
41
+ class << self; alias_method :application_error, :error; end
42
+
43
+ # @option jsonrpc [String]
44
+ # @option method [String]
45
+ # @option params [Hash<String|Symbol,Any>]
46
+ # @option id [String]
47
+ # @return [JSONRPC::Request]
48
+ #
49
+ # @api public
50
+ # @since 0.1.0
51
+ def request(jsonrpc: '2.0', method:, params:, id:)
52
+ JSONRPC::Request.new(jsonrpc:, method:, params:, id:)
53
+ end
54
+
55
+ # @option jsonrpc [String]
56
+ # @option method [String]
57
+ # @option params [Hash<Symbol,Any>]
58
+ # @return [JSONRPC::Notification]
59
+ #
60
+ # @api public
61
+ # @since 0.1.0
62
+ def notification(jsonrpc: '2.0', method:, params:)
63
+ JSONRPC::Notification.new(jsonrpc:, method:, params:)
64
+ end
65
+
66
+ # @param data [Hash]
67
+ # @option request_id [String, NilClass]
68
+ # @return [JSONRPC::ErrorResponse]
69
+ #
70
+ # @api public
71
+ # @since 0.1.0
72
+ def invalid_request_error(data = {}, request_id: nil)
73
+ error(
74
+ data,
75
+ code: JSONRPC::ERRORS[:invalid_request][:code],
76
+ message: JSONRPC::ERRORS[:invalid_request][:message],
77
+ request_id:
78
+ )
79
+ end
80
+
81
+ # @return [JSONRPC::ErrorResponse]
82
+ #
83
+ # @api public
84
+ # @since 0.1.0
85
+ def parse_error
86
+ error(
87
+ code: JSONRPC::ERRORS[:parse_error][:code],
88
+ message: JSONRPC::ERRORS[:parse_error][:message]
89
+ )
90
+ end
91
+
92
+ # @option request_id [String, NilClass]
93
+ # @return [JSONRPC::ErrorResponse]
94
+ #
95
+ # @api public
96
+ # @since 0.1.0
97
+ def jsonrpc_specification_violation_error(request_id: nil)
98
+ error(
99
+ code: JSONRPC::ERRORS[:jsonrpc_specification_violation][:code],
100
+ message: JSONRPC::ERRORS[:jsonrpc_specification_violation][:message],
101
+ request_id:
102
+ )
103
+ end
104
+
105
+ # @option request_id [String, NilClass]
106
+ # @return [JSONRPC::ErrorResponse]
107
+ #
108
+ # @api public
109
+ # @since 0.1.0
110
+ def method_not_found_error(request_id: nil)
111
+ error(
112
+ code: JSONRPC::ERRORS[:method_not_found][:code],
113
+ message: JSONRPC::ERRORS[:method_not_found][:message],
114
+ request_id:
115
+ )
116
+ end
117
+
118
+ # @param data [Hash<String|Symbol,Any>]
119
+ # @option request_id [String, NilClass]
120
+ # @return [JSONRPC::ErrorResponse]
121
+ #
122
+ # @api public
123
+ # @since 0.1.0
124
+ def invalid_params_error(data = {}, request_id: nil)
125
+ error(
126
+ data,
127
+ code: JSONRPC::ERRORS[:invalid_params][:code],
128
+ message: JSONRPC::ERRORS[:invalid_params][:message],
129
+ request_id:
130
+ )
131
+ end
132
+
133
+ # @param error_codes [*Array<String,Symbol>]
134
+ # @option error_context [Hash<String|Symbol,Any>]
135
+ # @option request_id [String, NilClass]
136
+ # @return [JSONRPC::ErrorResponse]
137
+ #
138
+ # @api public
139
+ # @since 0.1.0
140
+ def internal_error(*error_codes, error_context: {}, request_id: nil)
141
+ error(
142
+ { error_codes:, error_context: },
143
+ code: JSONRPC::ERRORS[:internal_error][:code],
144
+ message: JSONRPC::ERRORS[:internal_error][:message],
145
+ request_id:
146
+ )
147
+ end
148
+
149
+ # @param exception [Exception]
150
+ # @option request_id [String, NilClass]
151
+ # @return [JSONRPC::ErrorResponse]
152
+ #
153
+ # @api public
154
+ # @since 0.1.0
155
+ def detailed_internal_error(exception, request_id: nil)
156
+ internal_error(
157
+ error_context: {
158
+ error_class: exception.class,
159
+ error_message: exception.message,
160
+ error_backtrace: exception.backtrace,
161
+ error_object: exception
162
+ },
163
+ request_id:
164
+ )
165
+ end
166
+ end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONRPC
4
- VERSION = '0.0.1'
4
+ # @return [String]
5
+ #
6
+ # @api public
7
+ # @since 0.1.0
8
+ VERSION = '0.1.0'
5
9
  end
data/lib/jsonrpc.rb CHANGED
@@ -1,5 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'smart_core/types'
4
+ require 'smart_core/schema'
5
+ require 'smart_core/value-object'
6
+
7
+ # @api public
8
+ # @since 0.1.0
3
9
  module JSONRPC
4
10
  require_relative 'jsonrpc/version'
11
+ require_relative 'jsonrpc/request'
12
+ require_relative 'jsonrpc/notification'
13
+ require_relative 'jsonrpc/response'
14
+ require_relative 'jsonrpc/error_response'
15
+ require_relative 'jsonrpc/rpc_object'
16
+
17
+ # @return [Hash<Symbol,Hash<Symbol,String|Integer>>]
18
+ #
19
+ # @api public
20
+ # @since 0.1.0
21
+ ERRORS = {
22
+ parse_error: {
23
+ code: -32_700,
24
+ message: 'Parse Error'
25
+ },
26
+ invalid_request: {
27
+ code: -32_600,
28
+ message: 'Invalid Request'
29
+ },
30
+ method_not_found: {
31
+ code: -32_601,
32
+ message: 'Method Not Found'
33
+ },
34
+ invalid_params: {
35
+ code: -32_602,
36
+ message: 'Invalid Params'
37
+ },
38
+ internal_error: {
39
+ code: -32_603,
40
+ message: 'Internal Error'
41
+ },
42
+ unauthorized: {
43
+ code: -33_001,
44
+ message: 'Unauthorized'
45
+ },
46
+ application_error: {
47
+ code: -33_002,
48
+ message: 'Application Error'
49
+ },
50
+ jsonrpc_specification_violation: {
51
+ code: -33_003,
52
+ message: 'JSONRPC Specification Violation'
53
+ }
54
+ }.freeze
5
55
  end
@@ -1,3 +1,139 @@
1
- module JsonrpcInterface
1
+ module JSONRPC
2
2
  VERSION: String
3
+
4
+ # TODO:
5
+ # - try to return the record sub-hash value:
6
+ # -> before: Hash[Symbol, Hash[Symbol,untyped]]
7
+ # -> after (does not work): Hash[Symbol, { code: Integer, message: String }]
8
+ ERRORS: Hash[Symbol, Hash[Symbol,untyped]]
9
+
10
+ interface _RPCRequest
11
+ def notification?: () -> bool
12
+ def request?: () -> bool
13
+ end
14
+
15
+ interface _RPCResponse
16
+ def error?: () -> bool
17
+ def success?: () -> bool
18
+ end
19
+
20
+ class Request
21
+ include _RPCRequest
22
+
23
+ attr_reader jsonrpc: String
24
+ attr_reader method: String
25
+ attr_reader params: Hash[String|Symbol,untyped]
26
+ attr_reader id: String|nil
27
+
28
+ def initialize: (
29
+ jsonrpc: String,
30
+ method: String,
31
+ params: Hash[String|Symbol,untyped],
32
+ id: String
33
+ ) -> void
34
+ end
35
+
36
+ class Notification
37
+ include _RPCRequest
38
+
39
+ attr_reader jsonrpc: String
40
+ attr_reader method: String
41
+ attr_reader params: Hash[String|Symbol,untyped]
42
+
43
+ def initialize: (
44
+ jsonrpc: String,
45
+ method: String,
46
+ params: Hash[String|Symbol,untyped]
47
+ ) -> void
48
+ end
49
+
50
+ class Response
51
+ include _RPCResponse
52
+
53
+ attr_reader jsonrpc: String
54
+ attr_reader result: Hash[String|Symbol,untyped]
55
+ attr_reader id: String|nil
56
+
57
+ def initialize: (
58
+ jsonrpc: String,
59
+ result: Hash[String|Symbol,untyped],
60
+ id: String
61
+ ) -> void
62
+ end
63
+
64
+ class ErrorResponse
65
+ include _RPCResponse
66
+
67
+ attr_reader jsonrpc: String
68
+ attr_reader error: { code: Integer, message: String, data: Hash[String|Symbol,untyped] }
69
+ attr_reader id: String|nil
70
+
71
+ def initialize: (
72
+ jsonrpc: String,
73
+ error: {
74
+ code: Integer,
75
+ message: String,
76
+ data: Hash[String|Symbol,untyped]
77
+ },
78
+ id: String|nil
79
+ ) -> void
80
+ end
81
+
82
+ module RPCObject
83
+ def self?.response: (
84
+ ?Hash[String|Symbol,untyped],
85
+ ?request_id: String|nil
86
+ ) -> (Response|nil)
87
+
88
+ def self?.error: (
89
+ ?Hash[String|Symbol,untyped],
90
+ ?code: Integer,
91
+ ?message: String,
92
+ ?request_id: String|nil,
93
+ ) -> ErrorResponse
94
+
95
+ def self?.request: (
96
+ ?jsonrpc: String,
97
+ method: String,
98
+ params: Hash[String|Symbol,untyped],
99
+ id: String
100
+ ) -> Request
101
+
102
+ def self?.notification: (
103
+ ?jsonrpc: String,
104
+ method: String,
105
+ params: Hash[String|Symbol,untyped]
106
+ ) -> Notification
107
+
108
+ def self?.invalid_request_error: (
109
+ ?Hash[String|Symbol,untyped],
110
+ ?request_id: String|nil
111
+ ) -> ErrorResponse
112
+
113
+ def self?.parse_error: () -> ErrorResponse
114
+
115
+ def self?.jsonrpc_specification_violation_error: (
116
+ ?request_id: String|nil
117
+ ) -> ErrorResponse
118
+
119
+ def self?.method_not_found_error: (
120
+ ?request_id: String|nil
121
+ ) -> ErrorResponse
122
+
123
+ def self?.invalid_params_error: (
124
+ ?Hash[String|Symbol,untyped],
125
+ ?request_id: String|nil
126
+ ) -> ErrorResponse
127
+
128
+ def self?.internal_error: (
129
+ *String|Symbol,
130
+ ?error_context: Hash[String|Symbol,untyped],
131
+ ?request_id: String|nil
132
+ ) -> ErrorResponse
133
+
134
+ def self?.detailed_internal_error: (
135
+ Exception,
136
+ ?request_id: String|nil
137
+ ) -> ErrorResponse
138
+ end
3
139
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonrpc_interface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-28 00:00:00.000000000 Z
11
+ date: 2023-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: smart_schema
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: smart_types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: smart_value-object
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
13
55
  - !ruby/object:Gem::Dependency
14
56
  name: bundler
15
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +136,37 @@ dependencies:
94
136
  - - "~>"
95
137
  - !ruby/object:Gem::Version
96
138
  version: '0.14'
139
+ - !ruby/object:Gem::Dependency
140
+ name: steep
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.4'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.4'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rbs
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.1'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.1'
97
167
  description: JSONRPC Interface for Ruby projects realised in object oriented way.
168
+ JRPC Request, JRPC Notification, JRPC Response, JRPC Error Response, JRPC Object
169
+ Builder and JRPC Error Codes.
98
170
  email:
99
171
  - iamdaiver@gmail.com
100
172
  executables: []
@@ -111,10 +183,16 @@ files:
111
183
  - LICENSE.txt
112
184
  - README.md
113
185
  - Rakefile
186
+ - Steepfile
114
187
  - bin/console
115
188
  - bin/setup
116
189
  - jsonrpc_interface.gemspec
117
190
  - lib/jsonrpc.rb
191
+ - lib/jsonrpc/error_response.rb
192
+ - lib/jsonrpc/notification.rb
193
+ - lib/jsonrpc/request.rb
194
+ - lib/jsonrpc/response.rb
195
+ - lib/jsonrpc/rpc_object.rb
118
196
  - lib/jsonrpc/version.rb
119
197
  - lib/jsonrpc_interface.rb
120
198
  - sig/jsonrpc_interface.rbs