jsonrpc-middleware 0.6.0 → 0.7.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/.aiignore +6 -1
  3. data/.claude/agents/entire-search.md +25 -0
  4. data/.claude/agents/rbs-specialist.md +89 -0
  5. data/.claude/settings.json +84 -0
  6. data/.devcontainer/devcontainer.json +17 -0
  7. data/.dockerignore +16 -0
  8. data/.entire/.gitignore +5 -0
  9. data/.entire/settings.json +4 -0
  10. data/.rubocop.yml +26 -1
  11. data/.tool-versions +1 -1
  12. data/.yard-lint.yml +283 -0
  13. data/AGENTS.md +142 -0
  14. data/CHANGELOG.md +19 -0
  15. data/CLAUDE.md +2 -113
  16. data/Dockerfile +144 -0
  17. data/README.md +9 -17
  18. data/Rakefile +62 -11
  19. data/examples/procedures.rb +3 -1
  20. data/examples/rack/Gemfile.lock +4 -4
  21. data/examples/rack-echo/Gemfile.lock +4 -4
  22. data/examples/rails/Gemfile.lock +12 -5
  23. data/examples/rails/config/initializers/jsonrpc.rb +1 -1
  24. data/examples/rails-routing-dsl/config.ru +5 -5
  25. data/examples/rails-single-file/config.ru +1 -1
  26. data/examples/rails-single-file-routing/config.ru +1 -1
  27. data/examples/sinatra-classic/Gemfile.lock +11 -4
  28. data/examples/sinatra-modular/Gemfile.lock +11 -4
  29. data/lib/jsonrpc/batch_request.rb +8 -11
  30. data/lib/jsonrpc/batch_response.rb +6 -8
  31. data/lib/jsonrpc/configuration.rb +30 -4
  32. data/lib/jsonrpc/error.rb +7 -8
  33. data/lib/jsonrpc/errors/internal_error.rb +2 -0
  34. data/lib/jsonrpc/errors/invalid_params_error.rb +2 -0
  35. data/lib/jsonrpc/errors/invalid_request_error.rb +2 -0
  36. data/lib/jsonrpc/errors/method_not_found_error.rb +2 -0
  37. data/lib/jsonrpc/errors/parse_error.rb +2 -0
  38. data/lib/jsonrpc/helpers.rb +6 -0
  39. data/lib/jsonrpc/middleware.rb +12 -11
  40. data/lib/jsonrpc/notification.rb +7 -8
  41. data/lib/jsonrpc/parser.rb +13 -12
  42. data/lib/jsonrpc/railtie/batch_constraint.rb +1 -0
  43. data/lib/jsonrpc/railtie/mapper_extension.rb +2 -2
  44. data/lib/jsonrpc/railtie/method_constraint.rb +9 -0
  45. data/lib/jsonrpc/railtie/routes_dsl.rb +10 -15
  46. data/lib/jsonrpc/railtie.rb +2 -0
  47. data/lib/jsonrpc/response.rb +2 -2
  48. data/lib/jsonrpc/types.rb +1 -1
  49. data/lib/jsonrpc/validator.rb +14 -4
  50. data/lib/jsonrpc/version.rb +1 -1
  51. data/lib/jsonrpc.rb +3 -0
  52. data/rbs_collection.lock.yaml +476 -0
  53. data/rbs_collection.yaml +21 -0
  54. data/sig/jsonrpc/batch_request.rbs +17 -0
  55. data/sig/jsonrpc/batch_response.rbs +17 -0
  56. data/sig/jsonrpc/configuration.rbs +18 -0
  57. data/sig/jsonrpc/error.rbs +17 -0
  58. data/sig/jsonrpc/errors/internal_error.rbs +5 -0
  59. data/sig/jsonrpc/errors/invalid_params_error.rbs +5 -0
  60. data/sig/jsonrpc/errors/invalid_request_error.rbs +5 -0
  61. data/sig/jsonrpc/errors/method_not_found_error.rbs +5 -0
  62. data/sig/jsonrpc/errors/parse_error.rbs +5 -0
  63. data/sig/jsonrpc/middleware.rbs +20 -3
  64. data/sig/jsonrpc/notification.rbs +15 -0
  65. data/sig/jsonrpc/parser.rbs +7 -1
  66. data/sig/jsonrpc/request.rbs +18 -0
  67. data/sig/jsonrpc/response.rbs +19 -0
  68. data/sig/jsonrpc/validator.rbs +8 -0
  69. data/sig/jsonrpc.rbs +3 -156
  70. data/sig/multi_json.rbs +17 -0
  71. data/sig/type_definitions.rbs +11 -0
  72. data/sig/zeitwerk.rbs +10 -0
  73. metadata +34 -12
  74. data/.claude/commands/document.md +0 -105
  75. data/.claude/commands/gemfile/update.md +0 -52
  76. data/.claude/commands/test.md +0 -561
  77. data/.claude/docs/yard.md +0 -602
  78. data/.claude/settings.local.json +0 -15
  79. data/.yardstick.yml +0 -22
@@ -0,0 +1,8 @@
1
+ module JSONRPC
2
+ class Validator
3
+ @logger: Logger
4
+
5
+ def initialize: (?logger: Logger) -> void
6
+ def validate: (BatchRequest | Request | Notification) -> (Error | Array[Error?] | nil)
7
+ end
8
+ end
data/sig/jsonrpc.rbs CHANGED
@@ -1,164 +1,11 @@
1
1
  module JSONRPC
2
- VERSION: String
3
-
4
- # Method definitions that should be available
5
- interface _ToJson
6
- def to_json: (*untyped) -> String
7
- end
8
-
9
- interface _HashLike
10
- def []: (Symbol) -> untyped
11
- def []=: (Symbol, untyped) -> untyped
12
- end
13
-
14
- # Representing JSON-compatible types
15
- type json_scalar = String | Integer | Float | bool | nil
16
- type json_object = Hash[String, json_value]
17
- type json_array = Array[json_value]
18
- type json_value = json_scalar | json_object | json_array
19
-
20
2
  # Common types used across the library
21
3
  type params_type = Hash[untyped, untyped] | Array[untyped] | nil
22
4
  type id_type = String | Integer | nil
23
5
  type data_type = Hash[untyped, untyped] | Array[untyped] | String | Numeric | bool | nil
24
6
 
25
- # Hash with Symbol keys
26
- type symbol_hash = Hash[Symbol, untyped] & _ToJson
27
-
28
- class Error < StandardError
29
- attr_reader code: Integer
30
- attr_reader message: String
31
- attr_reader data: data_type
32
- attr_accessor request_id: Integer | String | nil
33
-
34
- def initialize: (code: Integer, message: String, ?data: data_type, ?request_id: id_type) -> void
35
- def to_h: -> symbol_hash
36
- def to_json: (*untyped) -> String
37
-
38
- private
39
-
40
- def validate_code: (Integer) -> void
41
- def validate_message: (String) -> void
42
- end
43
-
44
- class ParseError < Error
45
- def initialize: (?data: data_type, ?request_id: id_type) -> void
46
- end
47
-
48
- class InvalidRequestError < Error
49
- def initialize: (?data: data_type, ?request_id: id_type) -> void
50
- end
51
-
52
- class MethodNotFoundError < Error
53
- def initialize: (?data: data_type, ?request_id: id_type) -> void
54
- end
55
-
56
- class InvalidParamsError < Error
57
- def initialize: (?data: data_type, ?request_id: id_type) -> void
58
- end
59
-
60
- class InternalError < Error
61
- def initialize: (?data: data_type, ?request_id: id_type) -> void
62
- end
63
-
64
- class Request
65
- attr_reader jsonrpc: String
66
- attr_reader method: String
67
- attr_reader params: params_type
68
- attr_reader id: id_type
69
-
70
- def initialize: (method: String, ?params: params_type, id: id_type) -> void
71
- def to_h: -> symbol_hash
72
- def to_json: (*untyped) -> String
73
-
74
- private
75
-
76
- def validate_method: (String) -> void
77
- def validate_params: (params_type) -> void
78
- def validate_id: (id_type) -> void
79
- end
80
-
81
- class Response
82
- attr_reader jsonrpc: String
83
- attr_reader result: untyped
84
- attr_reader error: Error?
85
- attr_reader id: id_type
86
-
87
- def initialize: (?result: untyped, ?error: Error?, id: id_type) -> void
88
- def success?: -> bool
89
- def error?: -> bool
90
- def to_h: -> symbol_hash
91
- def to_json: (*untyped) -> String
92
-
93
- private
94
-
95
- def validate_result_and_error: (untyped, Error?) -> void
96
- def validate_id: (id_type) -> void
97
- end
98
-
99
- class Notification
100
- attr_reader jsonrpc: String
101
- attr_reader method: String
102
- attr_reader params: params_type
103
-
104
- def initialize: (method: String, ?params: params_type) -> void
105
- def to_h: -> symbol_hash
106
- def to_json: (*untyped) -> String
107
-
108
- private
109
- def validate_method: (String) -> void
110
- def validate_params: (params_type) -> void
111
- end
112
-
113
- class BatchRequest
114
- include Enumerable[Request | Notification]
115
-
116
- attr_reader requests: Array[Request | Notification]
117
-
118
- def initialize: (Array[Request | Notification]) -> void
119
- def to_h: -> Array[symbol_hash]
120
- def to_json: (*untyped) -> String
121
- def each: () { (Request | Notification) -> void } -> self
122
- | () -> Enumerator[Request | Notification, self]
123
-
124
- private
125
-
126
- def validate_requests: (Array[untyped]) -> void
127
- end
128
-
129
- class BatchResponse
130
- include Enumerable[Response]
131
-
132
- attr_reader responses: Array[Response]
133
-
134
- def initialize: (Array[Response]) -> void
135
- def to_h: -> Array[symbol_hash]
136
- def to_json: (*untyped) -> String
137
- def each: () { (Response) -> void } -> self
138
- | () -> Enumerator[Response, self]
139
-
140
- private
141
-
142
- def validate_responses: (Array[untyped]) -> void
143
- end
144
-
145
- module Errors
146
- class Error = JSONRPC::Error
147
- end
148
- end
149
-
150
- # External library signatures
151
- module Zeitwerk
152
- class Loader
153
- def self.for_gem: () -> Loader
154
- def enable_reloading: () -> void
155
- def collapse: (String) -> void
156
- def setup: () -> void
157
- def eager_load: () -> void
158
- end
159
- end
7
+ VERSION: String
160
8
 
161
- module JSON
162
- def self.parse: (String, ?untyped) -> untyped
163
- def self.generate: (untyped, ?untyped) -> String
9
+ def self.configure: () { (Configuration) -> void } -> void
10
+ def self.configuration: -> Configuration
164
11
  end
@@ -0,0 +1,17 @@
1
+ module MultiJson
2
+ class ParseError < StandardError
3
+ end
4
+
5
+ interface _Adapter
6
+ def name: () -> String
7
+ end
8
+
9
+ interface _Readable
10
+ def read: () -> String
11
+ end
12
+
13
+ def self.load: (String | _Readable string, Hash[interned, untyped]) -> Object?
14
+ def self.dump: (Object object, *Hash[interned, untyped] options) -> String
15
+ def self.use: (Symbol, String, Module, nil) -> untyped
16
+ def self.adapter: () -> _Adapter
17
+ end
@@ -0,0 +1,11 @@
1
+ # Representing JSON-compatible types
2
+ type json_scalar = String | Integer | Float | bool | nil
3
+ type json_object = Hash[String, json_value]
4
+ type json_array = Array[json_value]
5
+ type json_value = json_scalar | json_object | json_array
6
+
7
+ # Hash with Symbol keys
8
+ type symbol_hash = Hash[Symbol, untyped] & _ToJson
9
+
10
+ # Hash with String or Symbol keys
11
+ type interned_hash = Hash[interned, untyped] & _ToJson
data/sig/zeitwerk.rbs ADDED
@@ -0,0 +1,10 @@
1
+ # External library signatures
2
+ module Zeitwerk
3
+ class Loader
4
+ def self.for_gem: () -> Loader
5
+ def enable_reloading: () -> void
6
+ def collapse: (*(String | Pathname | Array[String | Pathname])) -> void
7
+ def setup: () -> void
8
+ def eager_load: (?force: boolish) -> void
9
+ end
10
+ end
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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wilson Silva
@@ -43,28 +43,28 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '1.17'
46
+ version: '1.21'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '1.17'
53
+ version: '1.21'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: zeitwerk
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '2.7'
60
+ version: '2.8'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '2.7'
67
+ version: '2.8'
68
68
  description: A Rack middleware implementing the JSON-RPC 2.0 protocol that integrates
69
69
  easily with all Rack-based applications (Rails, Sinatra, Hanami, etc).
70
70
  email:
@@ -74,21 +74,25 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".aiignore"
77
- - ".claude/commands/document.md"
78
- - ".claude/commands/gemfile/update.md"
79
- - ".claude/commands/test.md"
80
- - ".claude/docs/yard.md"
81
- - ".claude/settings.local.json"
77
+ - ".claude/agents/entire-search.md"
78
+ - ".claude/agents/rbs-specialist.md"
79
+ - ".claude/settings.json"
80
+ - ".devcontainer/devcontainer.json"
81
+ - ".dockerignore"
82
82
  - ".editorconfig"
83
+ - ".entire/.gitignore"
84
+ - ".entire/settings.json"
83
85
  - ".env.example"
84
86
  - ".overcommit.yml"
85
87
  - ".rspec"
86
88
  - ".rubocop.yml"
87
89
  - ".tool-versions"
88
- - ".yardstick.yml"
90
+ - ".yard-lint.yml"
91
+ - AGENTS.md
89
92
  - CHANGELOG.md
90
93
  - CLAUDE.md
91
94
  - CODE_OF_CONDUCT.md
95
+ - Dockerfile
92
96
  - Guardfile
93
97
  - LICENSE.txt
94
98
  - README.md
@@ -176,9 +180,27 @@ files:
176
180
  - lib/jsonrpc/types.rb
177
181
  - lib/jsonrpc/validator.rb
178
182
  - lib/jsonrpc/version.rb
183
+ - rbs_collection.lock.yaml
184
+ - rbs_collection.yaml
179
185
  - sig/jsonrpc.rbs
186
+ - sig/jsonrpc/batch_request.rbs
187
+ - sig/jsonrpc/batch_response.rbs
188
+ - sig/jsonrpc/configuration.rbs
189
+ - sig/jsonrpc/error.rbs
190
+ - sig/jsonrpc/errors/internal_error.rbs
191
+ - sig/jsonrpc/errors/invalid_params_error.rbs
192
+ - sig/jsonrpc/errors/invalid_request_error.rbs
193
+ - sig/jsonrpc/errors/method_not_found_error.rbs
194
+ - sig/jsonrpc/errors/parse_error.rbs
180
195
  - sig/jsonrpc/middleware.rbs
196
+ - sig/jsonrpc/notification.rbs
181
197
  - sig/jsonrpc/parser.rbs
198
+ - sig/jsonrpc/request.rbs
199
+ - sig/jsonrpc/response.rbs
200
+ - sig/jsonrpc/validator.rbs
201
+ - sig/multi_json.rbs
202
+ - sig/type_definitions.rbs
203
+ - sig/zeitwerk.rbs
182
204
  homepage: https://github.com/wilsonsilva/jsonrpc-middleware
183
205
  licenses:
184
206
  - MIT
@@ -201,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
223
  - !ruby/object:Gem::Version
202
224
  version: '0'
203
225
  requirements: []
204
- rubygems_version: 3.7.2
226
+ rubygems_version: 4.0.12
205
227
  specification_version: 4
206
228
  summary: Rack middleware implementing the JSON-RPC 2.0 protocol.
207
229
  test_files: []
@@ -1,105 +0,0 @@
1
- # Document
2
-
3
- Generates documentation for Ruby code using YARD with 100% coverage enforcement.
4
-
5
- ## Commands
6
-
7
- Generate documentation:
8
- ```bash
9
- bundle exec rake yard
10
- ```
11
-
12
- Format YARD comments:
13
- ```bash
14
- bundle exec rake yard:format
15
- ```
16
-
17
- Verify 100% documentation coverage:
18
- ```bash
19
- bundle exec rake verify_measurements
20
- ```
21
-
22
- Check for documentation quality issues:
23
- ```bash
24
- bundle exec rake yard:junk
25
- ```
26
-
27
- Generate coverage report:
28
- ```bash
29
- bundle exec rake yardstick_measure
30
- ```
31
-
32
- ## Configuration
33
-
34
- Requires `.yardstick.yml` in project root with 100% threshold:
35
- ```yaml
36
- threshold: 100
37
- rules:
38
- ApiTag::Presence: { enabled: true }
39
- ApiTag::Inclusion: { enabled: true }
40
- ApiTag::ProtectedMethod: { enabled: true }
41
- ApiTag::PrivateMethod: { enabled: true }
42
- ExampleTag: { enabled: true }
43
- ReturnTag: { enabled: true }
44
- Summary::Presence: { enabled: true }
45
- Summary::Delimiter: { enabled: true }
46
- ```
47
-
48
- ## Coverage Report
49
-
50
- After running measurement, check detailed line-by-line issues:
51
- ```bash
52
- cat measurements/report.txt
53
- ```
54
-
55
- Report shows specific file, line number, method, and documentation issues that need fixing.
56
-
57
- ## Documentation Standards
58
-
59
- ### Required Tags
60
- - Every public/private method, class, and module requires `@api public` or `@api private`
61
- - All parameters: `@param name [Type] Description`
62
- - All returns: `@return [Type] Description` (use `[void]` if no return)
63
- - Examples required for all public methods: `@example Description`
64
- - Error conditions: `@raise [ExceptionClass] When this occurs`
65
-
66
- ### Type Notation
67
- - Use `String` not `string`
68
- - Arrays: `Array<String>` for string arrays
69
- - Hashes: `Hash{String=>Object}` for hash types
70
- - Use `Boolean` not `bool`, `Integer` not `int`
71
- - Nullable types: `String, nil` or `String|nil`
72
-
73
- ### Formatting Rules
74
- - Blank lines required between YARD tag groups
75
- - Exception: `@param` and `@option` tags can be grouped together
76
- - Wrap class/method names in `+` markers: `+PrivateKey+`
77
- - Cross-reference related methods: `@see #other_method`
78
-
79
- ### Documentation Structure
80
- ```ruby
81
- # Brief one-line summary ending with period.
82
- #
83
- # @api public
84
- #
85
- # @example Description of example
86
- # code_example
87
- # result # => expected_output
88
- #
89
- # @param name [Type] Description
90
- # @param other [Type] Other description
91
- #
92
- # @return [Type] Description
93
- #
94
- # @raise [ExceptionClass] When this exception occurs
95
- #
96
- def method_name
97
- end
98
- ```
99
-
100
- ## Integration
101
-
102
- Documentation verification is included in the quality assurance pipeline:
103
- ```bash
104
- bundle exec rake qa
105
- ```
@@ -1,52 +0,0 @@
1
- ---
2
- allowed-tools: Bash(bundle :*), Bash(git :*), Read, Edit, MultiEdit, Glob
3
- description: Update Gemfile dependencies to latest minor versions
4
- argument-hint: [gemfile] [commit]
5
- ---
6
-
7
- Update the dependencies in the specified Gemfile (or ./Gemfile if no path provided) to their latest minor versions while
8
- preserving major version constraints. Only update MAJOR.MINOR versions, never PATCH versions unless explicitly needed.
9
-
10
- Steps:
11
- 1. Read the Gemfile at the specified path (or ./Gemfile if $ARGUMENTS is empty)
12
- 2. Read the corresponding Gemfile.lock to get current resolved versions
13
- 3. Run `bundle outdated --only-explicit` to check for available minor updates of explicitly declared gems
14
- 4. For each gem in Gemfile, check if Gemfile.lock has a newer minor version than the current Gemfile constraint allows
15
- 5. Update gem version constraints to match the minor version from Gemfile.lock or latest available, whichever is newer (MAJOR.MINOR format)
16
- 6. Use pessimistic version constraints (~> MAJOR.MINOR) to prevent automatic patch updates
17
- 7. Preserve any existing version operators but ensure they follow minor-only update strategy
18
- 8. Run `bundle update` to apply the changes
19
- 7. Skip step 8, 9 and 10 if --commit flag is not provided
20
- 8. Stage Gemfile (only if not gitignored)
21
- 9. Verify if Gemfile.lock is tracked and not gitignored. If both conditions are met, stage it for commit.
22
- 10. Create a git commit with message 'Update development dependencies' and a description listing all updated gems with their old and new versions like:
23
-
24
- <commit-message>
25
- Updated gems:
26
- - rubocop: 1.75.2 → 1.78.0
27
- - rubocop-yard: 0.10.0 → 1.0.0
28
- </commit-message>
29
-
30
- 11. If any dependencies were updated, respond only with the update message. And if the user has chose to commit,
31
- include the update commit message. Otherwise, respond only with the no op message.
32
-
33
- <update-message>
34
- Updated gems:
35
- - rbs: 3.8 → 3.9
36
- - rubocop: 1.78 → 1.80
37
- - rubocop-rspec: 3.6 → 3.7
38
-
39
- <update-commit-message>The changes have been committed with the message "Update development dependencies".</update-commit-message>
40
- </update-message>
41
-
42
- <no-op-message>All dependencies are up to date.</no-op-message>
43
-
44
- Key bundle outdated flags used:
45
- - `--only-explicit`: Only show gems explicitly listed in Gemfile (not dependencies)
46
- - No `--local` flag to ensure remote gem sources are checked for latest versions
47
-
48
- Arguments:
49
- - `gemfile`: Gemfile path (defaults to ./Gemfile if not provided)
50
- - `--commit`: Create a git commit after updating dependencies with message 'Update development dependencies' and a description listing all updated gems with their old and new versions
51
-
52
- Gemfile path: ${ARGUMENTS:-./Gemfile}