connect_rpc_rails 0.1.0 → 0.2.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/CHANGELOG.md +16 -0
- data/README.md +88 -245
- data/lib/connect_rpc_rails/codec.rb +9 -0
- data/lib/connect_rpc_rails/controller.rb +142 -62
- data/lib/connect_rpc_rails/exceptions_app.rb +13 -3
- data/lib/connect_rpc_rails/get_query.rb +70 -0
- data/lib/connect_rpc_rails/message_validatable.rb +208 -0
- data/lib/connect_rpc_rails/protovalidate.rb +12 -0
- data/lib/connect_rpc_rails/routing.rb +1 -1
- data/lib/connect_rpc_rails/service_registration.rb +7 -1
- data/lib/connect_rpc_rails/version.rb +1 -1
- data/lib/connect_rpc_rails.rb +1 -0
- data/sig/generated/connect_rpc_rails/codec.rbs +4 -0
- data/sig/generated/connect_rpc_rails/controller.rbs +63 -23
- data/sig/generated/connect_rpc_rails/exceptions_app.rbs +6 -2
- data/sig/generated/connect_rpc_rails/get_query.rbs +47 -0
- data/sig/generated/connect_rpc_rails/message_validatable.rbs +96 -0
- data/sig/generated/connect_rpc_rails/protovalidate.rbs +2 -0
- data/sig/generated/connect_rpc_rails/routing.rbs +1 -1
- data/sig/generated/connect_rpc_rails/service_registration.rbs +8 -2
- metadata +49 -1
|
@@ -15,6 +15,10 @@ module ConnectRpcRails
|
|
|
15
15
|
# : (String?) -> _Codec?
|
|
16
16
|
def self.for_content_type: (String?) -> _Codec?
|
|
17
17
|
|
|
18
|
+
# The codec a Connect GET names in its `encoding` query parameter.
|
|
19
|
+
# : (String?) -> _Codec?
|
|
20
|
+
def self.for_name: (String?) -> _Codec?
|
|
21
|
+
|
|
18
22
|
module Json
|
|
19
23
|
CONTENT_TYPE: String
|
|
20
24
|
|
|
@@ -56,6 +56,9 @@ module ConnectRpcRails
|
|
|
56
56
|
|
|
57
57
|
UNKNOWN_METHOD_PARAM: ::String
|
|
58
58
|
|
|
59
|
+
# The request compression the transport accepts, advertised when a call uses another.
|
|
60
|
+
SUPPORTED_COMPRESSION: Array[String]
|
|
61
|
+
|
|
59
62
|
# The one `rescue_responses` entry that doesn't become a Connect error: #action_missing
|
|
60
63
|
# raises ActionNotFound for a name that isn't an RPC, which means the app routed
|
|
61
64
|
# something to an action this controller doesn't have. That is a misconfiguration for
|
|
@@ -112,14 +115,15 @@ module ConnectRpcRails
|
|
|
112
115
|
# Connect actions decode the body themselves and never read `params`, so skip
|
|
113
116
|
# Rails' lazy body param parsing: it would deserialize a JSON body a second time
|
|
114
117
|
# (instrumentation reads filtered_parameters) and leak request payloads into
|
|
115
|
-
# logs. Query params still parse; instrumentation
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
118
|
+
# logs. Query params other than a GET's Connect parameters still parse; instrumentation
|
|
119
|
+
# is otherwise unaffected.
|
|
120
|
+
# Runs before instrumentation reads the params, so it decodes the Connect message (a
|
|
121
|
+
# POST's body, a GET's `message`) here, exactly once, and reuses it two ways: the
|
|
122
|
+
# typed message drives the action, and its hash form populates `request_parameters`
|
|
123
|
+
# — so the standard Rails request log, `config.filter_parameters`, and APM see the
|
|
124
|
+
# request without Rails parsing it a second time. Also reports the wire format for
|
|
125
|
+
# logs/instrumentation (via the formats header rather than `request.format=`, which
|
|
126
|
+
# would inject a :format key into params).
|
|
123
127
|
def process_action: (*untyped) -> untyped
|
|
124
128
|
|
|
125
129
|
# The RPC method is the controller's own method, so the transport wraps dispatch
|
|
@@ -153,6 +157,27 @@ module ConnectRpcRails
|
|
|
153
157
|
|
|
154
158
|
private def connect_request_params: () -> untyped
|
|
155
159
|
|
|
160
|
+
# The serialized request message: the body of a POST, the `message` parameter of a GET.
|
|
161
|
+
# : () -> String
|
|
162
|
+
private def connect_request_bytes: () -> String
|
|
163
|
+
|
|
164
|
+
# Connect serves an RPC over GET only when it is unary and its `.proto` declares it free of
|
|
165
|
+
# side effects.
|
|
166
|
+
# : (ServiceRegistration::Rpc) -> bool
|
|
167
|
+
private def connect_get_allowed?: (ServiceRegistration::Rpc) -> bool
|
|
168
|
+
|
|
169
|
+
# Whether this call is a Connect GET, which carries its request in the query string.
|
|
170
|
+
# : () -> bool
|
|
171
|
+
private def connect_get?: () -> bool
|
|
172
|
+
|
|
173
|
+
# : () -> GetQuery
|
|
174
|
+
private def connect_get_query: () -> GetQuery
|
|
175
|
+
|
|
176
|
+
# A GET's query parameters are its request, which `request_parameters` already holds
|
|
177
|
+
# decoded, so `params` shows the message once. A query Rails refuses, such as a binary
|
|
178
|
+
# message sent without base64, keeps no parameters.
|
|
179
|
+
private def exclude_connect_query_parameters: () -> untyped
|
|
180
|
+
|
|
156
181
|
# The transport preconditions have all passed by the time this runs (see
|
|
157
182
|
# #validate_connect_request), so this is the wire round-trip and nothing else. The RPC
|
|
158
183
|
# runs on this controller instance — the one Rails built for this request — and takes
|
|
@@ -160,15 +185,25 @@ module ConnectRpcRails
|
|
|
160
185
|
# DSL checks that at boot), so there is no missing-method case.
|
|
161
186
|
private def dispatch_connect_rpc: (untyped rpc) -> untyped
|
|
162
187
|
|
|
163
|
-
# The codec for this call
|
|
164
|
-
#
|
|
188
|
+
# The codec for this call. Never missing once the action runs: #validate_connect_request
|
|
189
|
+
# answers a codec it has none for with a 415.
|
|
165
190
|
# : () -> Codec::_Codec
|
|
166
191
|
private def connect_codec: () -> Codec::_Codec
|
|
167
192
|
|
|
168
|
-
#
|
|
169
|
-
#
|
|
193
|
+
# The codec the caller named: a GET's `encoding` parameter, a POST's content-type. Nil
|
|
194
|
+
# when no codec handles it.
|
|
195
|
+
# : () -> Codec::_Codec?
|
|
196
|
+
private def connect_requested_codec: () -> Codec::_Codec?
|
|
197
|
+
|
|
198
|
+
# Connect rejects unsupported request compression with `unimplemented`, naming what it
|
|
199
|
+
# can accept in both `accept-encoding` and the message. A GET names its compression in
|
|
200
|
+
# the query.
|
|
170
201
|
private def reject_unsupported_encoding: () -> untyped
|
|
171
202
|
|
|
203
|
+
# `connect=v1` is optional, as the protocol lets a server accept a GET without it. Any
|
|
204
|
+
# other version is a revision of the protocol this server does not speak.
|
|
205
|
+
private def reject_unsupported_protocol_version: () -> untyped
|
|
206
|
+
|
|
172
207
|
# The decoded request message, for the action to read the way an HTTP action reads
|
|
173
208
|
# `params`. Assigned during decode, so callbacks see it too.
|
|
174
209
|
# : () -> untyped
|
|
@@ -206,17 +241,22 @@ module ConnectRpcRails
|
|
|
206
241
|
# : () { (?) -> untyped } -> untyped
|
|
207
242
|
private def enforce_connect_deadline: () { (?) -> untyped } -> untyped
|
|
208
243
|
|
|
209
|
-
# The handler `
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
#
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
|
|
244
|
+
# The handler every `rescue_from` the library installs points at.
|
|
245
|
+
private def render_connect_exception: (untyped exception) -> untyped
|
|
246
|
+
|
|
247
|
+
# The Connect error to send for a rescued exception. Override to add details every
|
|
248
|
+
# error should carry, the way ExceptionsApp#connect_error_for is overridden for errors
|
|
249
|
+
# that escape the controller.
|
|
250
|
+
#
|
|
251
|
+
# A mapped exception takes its code from `map_connect_errors`, which overrides the
|
|
252
|
+
# `rescue_responses` classification. That status is read off the nearest ancestor the
|
|
253
|
+
# registry names, since `rescue_from` matches subclasses too and a subclass isn't a key
|
|
254
|
+
# (an `ActiveRecord::RecordNotUnique` is classified as the `StatementInvalid` it
|
|
255
|
+
# descends from). Read with `fetch`, because the registry answers anything at all with
|
|
256
|
+
# a default of :internal_server_error — which would stop the walk on the first ancestor
|
|
257
|
+
# and call every subclass a 500.
|
|
258
|
+
# : (Exception) -> Error
|
|
259
|
+
private def connect_error_for: (Exception) -> Error
|
|
220
260
|
|
|
221
261
|
private def render_connect_error: (untyped error) -> untyped
|
|
222
262
|
|
|
@@ -7,8 +7,9 @@ module ConnectRpcRails
|
|
|
7
7
|
#
|
|
8
8
|
# config.exceptions_app = ConnectRpcRails::ExceptionsApp.new(MyExceptions.new(Rails.public_path))
|
|
9
9
|
#
|
|
10
|
-
# A Connect request is recognized by `connect-protocol-version
|
|
11
|
-
#
|
|
10
|
+
# A Connect request is recognized by the `connect-protocol-version` header Connect clients
|
|
11
|
+
# send on a unary POST, or by the `connect=v1` query parameter they send on a GET; anything
|
|
12
|
+
# else reaches the wrapped app untouched.
|
|
12
13
|
class ExceptionsApp
|
|
13
14
|
# `connect-protocol-version`, as Rack names it in the env.
|
|
14
15
|
PROTOCOL_VERSION_HEADER: ::String
|
|
@@ -19,6 +20,9 @@ module ConnectRpcRails
|
|
|
19
20
|
# : (Hash[String, untyped]) -> [Integer, Hash[String, String], Array[String]]
|
|
20
21
|
def call: (Hash[String, untyped]) -> [ Integer, Hash[String, String], Array[String] ]
|
|
21
22
|
|
|
23
|
+
# : (Hash[String, untyped]) -> bool
|
|
24
|
+
private def connect_request?: (Hash[String, untyped]) -> bool
|
|
25
|
+
|
|
22
26
|
# The error to send for an escaped exception. The message is the status's own text,
|
|
23
27
|
# never the exception's, which can quote internals. Override in a subclass to add
|
|
24
28
|
# details every error should carry.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Generated from lib/connect_rpc_rails/get_query.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module ConnectRpcRails
|
|
4
|
+
# The query string of a Connect unary GET, which carries the codec, compression and message
|
|
5
|
+
# a POST sends as headers and body:
|
|
6
|
+
#
|
|
7
|
+
# GET /greet.v1.GreetService/SayHello?connect=v1&encoding=json&message=%7B%22name%22%3A%22Ada%22%7D
|
|
8
|
+
class GetQuery
|
|
9
|
+
# The parameters the protocol defines. Any other parameter is allowed and ignored.
|
|
10
|
+
PARAMS: Array[String]
|
|
11
|
+
|
|
12
|
+
# The `connect` value Connect clients send, the GET counterpart of `connect-protocol-version: 1`.
|
|
13
|
+
PROTOCOL_VERSION: String
|
|
14
|
+
|
|
15
|
+
# The RFC 4648 §5 alphabet. Base64.urlsafe_decode64 checks the padding and the length, but
|
|
16
|
+
# also takes "+" and "/" from the standard alphabet.
|
|
17
|
+
URL_SAFE_BASE64: Regexp
|
|
18
|
+
|
|
19
|
+
# Raised when the `message` parameter is missing or is not the base64 it claims to be.
|
|
20
|
+
class InvalidMessage < StandardError
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Each parameter takes its first value. An invalid percent-escape is kept as written, as
|
|
24
|
+
# URI.decode_www_form does, so it fails as an unknown value rather than being dropped. The
|
|
25
|
+
# query is decoded as binary, because decoding as UTF-8 scrubs the bytes of an unencoded
|
|
26
|
+
# binary message; values are then tagged UTF-8 without being checked.
|
|
27
|
+
# : (String) -> GetQuery
|
|
28
|
+
def self.parse: (String) -> GetQuery
|
|
29
|
+
|
|
30
|
+
# : (Hash[String, String]) -> void
|
|
31
|
+
def initialize: (Hash[String, String]) -> void
|
|
32
|
+
|
|
33
|
+
# : () -> String?
|
|
34
|
+
def connect: () -> String?
|
|
35
|
+
|
|
36
|
+
# : () -> String?
|
|
37
|
+
def encoding: () -> String?
|
|
38
|
+
|
|
39
|
+
# : () -> String?
|
|
40
|
+
def compression: () -> String?
|
|
41
|
+
|
|
42
|
+
# The `message` parameter's bytes. With `base64=1` it is URL-safe base64, padded or not;
|
|
43
|
+
# any other `base64` value is ignored, per the protocol.
|
|
44
|
+
# : () -> String
|
|
45
|
+
def message: () -> String
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Generated from lib/connect_rpc_rails/message_validatable.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module ConnectRpcRails
|
|
4
|
+
# Checks a Connect request against the `buf.validate` rules of its message before the RPC
|
|
5
|
+
# runs, and answers a violation the way AIP-193 describes: `invalid_argument`, with a
|
|
6
|
+
# `google.rpc.BadRequest` naming each field.
|
|
7
|
+
#
|
|
8
|
+
# class GreetController < ActionController::API
|
|
9
|
+
# include ConnectRpcRails::Controller
|
|
10
|
+
# include ConnectRpcRails::MessageValidatable
|
|
11
|
+
# include BearerAuthentication
|
|
12
|
+
# connect_service "greet.v1.GreetService"
|
|
13
|
+
#
|
|
14
|
+
# def say_hello = ...
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# Fields are named in the caller's encoding: `preferredLanguage` for a JSON request,
|
|
18
|
+
# `preferred_language` for a binary one. `google.rpc.BadRequest` is looked up in the
|
|
19
|
+
# descriptor pool rather than required, because googleapis belongs to the application: it
|
|
20
|
+
# generates `google/rpc/error_details.proto` alongside its own protos, or bundles
|
|
21
|
+
# googleapis-common-protos-types.
|
|
22
|
+
#
|
|
23
|
+
# A violation raises ViolationError, which the concern rescues into the Connect error
|
|
24
|
+
# #connect_error_for_violation builds. Override that method to answer differently. Opt a
|
|
25
|
+
# controller out with `skip_before_action :validate_connect_message!` at its top.
|
|
26
|
+
# @rbs module-self ActionController::API
|
|
27
|
+
# @rbs module-self Controller
|
|
28
|
+
module MessageValidatable : ActionController::API, Controller
|
|
29
|
+
extend ActiveSupport::Concern
|
|
30
|
+
|
|
31
|
+
# Raised when `google.rpc.BadRequest` is not in the descriptor pool.
|
|
32
|
+
class MissingDescriptorError < StandardError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Raised when a request breaks a rule its message declares.
|
|
36
|
+
class ViolationError < StandardError
|
|
37
|
+
# @return [Array<Protovalidate::Violation>]
|
|
38
|
+
attr_reader violations: Array[untyped]
|
|
39
|
+
|
|
40
|
+
# @return [Object] the request message the violations were found in
|
|
41
|
+
attr_reader request_message: untyped
|
|
42
|
+
|
|
43
|
+
# : (Array[untyped] violations, untyped request_message) -> void
|
|
44
|
+
def initialize: (Array[untyped] violations, untyped request_message) -> void
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
BAD_REQUEST: String
|
|
48
|
+
|
|
49
|
+
# AIP-193: a FieldViolation's reason is UPPER_SNAKE_CASE and at most 63 characters.
|
|
50
|
+
REASON_PATTERN: Regexp
|
|
51
|
+
|
|
52
|
+
# Published for a rule id that cannot be a reason, such as a CEL rule named in lowercase.
|
|
53
|
+
FALLBACK_REASON: String
|
|
54
|
+
|
|
55
|
+
# Rails appends a re-registered callback to the end of the chain, so defining an RPC
|
|
56
|
+
# moves the validation behind the authentication a controller declares above it. An
|
|
57
|
+
# invalid request answered before an unauthenticated one would tell a caller what a valid
|
|
58
|
+
# request looks like. No entry means the controller skipped it, and it stays skipped.
|
|
59
|
+
def method_added: (untyped method_name) -> untyped
|
|
60
|
+
|
|
61
|
+
# The violated field as `parts[0].part_name`, each segment resolved against the descriptor
|
|
62
|
+
# so it is spelled the way the caller's encoding spells it. Empty for a message-level rule.
|
|
63
|
+
# : (untyped path, untyped message_class, json_names: bool) -> String
|
|
64
|
+
def self.field_path: (untyped path, untyped message_class, json_names: bool) -> String
|
|
65
|
+
|
|
66
|
+
# The message a path continues into after this field: for a map, the value's type rather
|
|
67
|
+
# than the synthetic entry, because the key is the subscript and not a segment.
|
|
68
|
+
# : (untyped field) -> untyped
|
|
69
|
+
def self.field_message: (untyped field) -> untyped
|
|
70
|
+
|
|
71
|
+
# : (untyped element) -> String
|
|
72
|
+
def self.subscript: (untyped element) -> String
|
|
73
|
+
|
|
74
|
+
# The rule id as a reason constant: `string.min_len` becomes `STRING_MIN_LEN`.
|
|
75
|
+
# : (String rule_id) -> String
|
|
76
|
+
def self.reason: (String rule_id) -> String
|
|
77
|
+
|
|
78
|
+
# A googleapis message class, looked up in the descriptor pool.
|
|
79
|
+
# : (String name) -> untyped
|
|
80
|
+
def self.googleapis_class: (String name) -> untyped
|
|
81
|
+
|
|
82
|
+
# : () -> void
|
|
83
|
+
private def validate_connect_message!: () -> void
|
|
84
|
+
|
|
85
|
+
# The Connect error a violation is answered with: `invalid_argument` with a
|
|
86
|
+
# `google.rpc.BadRequest`, naming each field the way this request's encoding spells it.
|
|
87
|
+
# Override to answer differently.
|
|
88
|
+
# : (ViolationError error) -> Error
|
|
89
|
+
private def connect_error_for_violation: (ViolationError error) -> Error
|
|
90
|
+
|
|
91
|
+
# Raised rather than only built, so the Connect error carries the violation as its cause for
|
|
92
|
+
# whatever reports it.
|
|
93
|
+
# : (ViolationError error) -> void
|
|
94
|
+
private def render_connect_violation: (ViolationError error) -> void
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -24,7 +24,7 @@ module ConnectRpcRails
|
|
|
24
24
|
# service but not that method, so it is answered `unimplemented` the way a declared RPC
|
|
25
25
|
# nobody implements always is.
|
|
26
26
|
#
|
|
27
|
-
# Every RPC the descriptor declares becomes one
|
|
27
|
+
# Every RPC the descriptor declares becomes one `/<pkg.Service>/<Method>` route to
|
|
28
28
|
# the action implementing it (1 RPC = 1 action), so the protobuf definition is the only
|
|
29
29
|
# place the method list lives. A declared RPC the controller doesn't implement is
|
|
30
30
|
# answered Connect `unimplemented` by the controller, not by a route. After the RPC
|
|
@@ -16,6 +16,8 @@ module ConnectRpcRails
|
|
|
16
16
|
# so leftover instance state could leak between callers, whereas Rails builds a
|
|
17
17
|
# controller per request.
|
|
18
18
|
class ServiceRegistration
|
|
19
|
+
# `idempotency_level` is the method option's enum symbol: `:NO_SIDE_EFFECTS`, `:IDEMPOTENT`
|
|
20
|
+
# or `:IDEMPOTENCY_UNKNOWN`. `streaming` is true when either side of the RPC streams.
|
|
19
21
|
class Rpc < Struct[untyped]
|
|
20
22
|
attr_accessor name(): untyped
|
|
21
23
|
|
|
@@ -25,8 +27,12 @@ module ConnectRpcRails
|
|
|
25
27
|
|
|
26
28
|
attr_accessor output_class(): untyped
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
attr_accessor idempotency_level(): untyped
|
|
31
|
+
|
|
32
|
+
attr_accessor streaming(): untyped
|
|
33
|
+
|
|
34
|
+
def self.new: (?name: untyped, ?action: untyped, ?input_class: untyped, ?output_class: untyped, ?idempotency_level: untyped, ?streaming: untyped) -> instance
|
|
35
|
+
| ({ ?name: untyped, ?action: untyped, ?input_class: untyped, ?output_class: untyped, ?idempotency_level: untyped, ?streaming: untyped }) -> instance
|
|
30
36
|
end
|
|
31
37
|
|
|
32
38
|
attr_reader service_name: String
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: connect_rpc_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- IVRy Inc.
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: base64
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: google-protobuf
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -37,6 +51,34 @@ dependencies:
|
|
|
37
51
|
- - "~>"
|
|
38
52
|
- !ruby/object:Gem::Version
|
|
39
53
|
version: '4.26'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: googleapis-common-protos-types
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.21'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '1.21'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: protovalidate
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 0.1.0.beta3
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 0.1.0.beta3
|
|
40
82
|
- !ruby/object:Gem::Dependency
|
|
41
83
|
name: puma
|
|
42
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -166,6 +208,9 @@ files:
|
|
|
166
208
|
- lib/connect_rpc_rails/controller.rb
|
|
167
209
|
- lib/connect_rpc_rails/errors.rb
|
|
168
210
|
- lib/connect_rpc_rails/exceptions_app.rb
|
|
211
|
+
- lib/connect_rpc_rails/get_query.rb
|
|
212
|
+
- lib/connect_rpc_rails/message_validatable.rb
|
|
213
|
+
- lib/connect_rpc_rails/protovalidate.rb
|
|
169
214
|
- lib/connect_rpc_rails/railtie.rb
|
|
170
215
|
- lib/connect_rpc_rails/routing.rb
|
|
171
216
|
- lib/connect_rpc_rails/service_registration.rb
|
|
@@ -175,6 +220,9 @@ files:
|
|
|
175
220
|
- sig/generated/connect_rpc_rails/controller.rbs
|
|
176
221
|
- sig/generated/connect_rpc_rails/errors.rbs
|
|
177
222
|
- sig/generated/connect_rpc_rails/exceptions_app.rbs
|
|
223
|
+
- sig/generated/connect_rpc_rails/get_query.rbs
|
|
224
|
+
- sig/generated/connect_rpc_rails/message_validatable.rbs
|
|
225
|
+
- sig/generated/connect_rpc_rails/protovalidate.rbs
|
|
178
226
|
- sig/generated/connect_rpc_rails/railtie.rbs
|
|
179
227
|
- sig/generated/connect_rpc_rails/routing.rbs
|
|
180
228
|
- sig/generated/connect_rpc_rails/service_registration.rbs
|