taro 2.1.0 → 2.3.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 +12 -0
- data/README.md +29 -25
- data/lib/taro/config.rb +2 -0
- data/lib/taro/declaration.rb +1 -1
- data/lib/taro/rails/railtie.rb +2 -0
- data/lib/taro/types/base_type.rb +1 -0
- data/lib/taro/types/field.rb +1 -0
- data/lib/taro/types/rails_params_type.rb +10 -0
- data/lib/taro/types/shared/caching.rb +3 -2
- data/lib/taro/types/shared/derived_types.rb +5 -3
- data/lib/taro/types/shared/object_coercion.rb +14 -0
- data/lib/taro/types/shared/rendering.rb +3 -5
- data/lib/taro/types/shared/type_class.rb +12 -0
- data/lib/taro/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c96d6fd71ad22df31d5ab4cefb09389fd7ed5b41b5dd8821132fa2c5fa322837
|
4
|
+
data.tar.gz: f56362229e93f2f8c51a5490245d4a37e224015fecd42bb86a35926a01e8d776
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34ad2aedee3c3a21973420ca5e1185024c7d6b127ee9ca914b847134939bcd136e70f10130607b8392ce8044dfcb7c8014fa306d00d81b81266d68fcdad19b95
|
7
|
+
data.tar.gz: 1bec2fbada3a23267f87195323b2b112297c21e78c22281071bd2ec84a7359f78836ed250e85ae3f3d1765f428dd7ff1bdaaf92f5df2bd17883abed11b7a39eb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [2.3.0] - 2025-02-24
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- `Taro.config.raise_for_undeclared_params`
|
8
|
+
|
9
|
+
## [2.2.0] - 2025-02-22
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- error message when incorrectly chaining `with_cache`
|
14
|
+
|
3
15
|
## [2.1.0] - 2025-02-21
|
4
16
|
|
5
17
|
### Added
|
data/README.md
CHANGED
@@ -140,6 +140,14 @@ Requests are automatically validated to match the declared input schema, unless
|
|
140
140
|
Taro.config.parse_params = false
|
141
141
|
```
|
142
142
|
|
143
|
+
There is also an option to raise an error if any undeclared params are submitted:
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
Taro.config.raise_for_undeclared_params = true
|
147
|
+
```
|
148
|
+
|
149
|
+
This option is similar to `action_on_unpermitted_parameters = :raise` in Rails and is most useful in dev and test environments. The railtie enables it automatically in these environments.
|
150
|
+
|
143
151
|
#### Response validation
|
144
152
|
|
145
153
|
Responses are automatically validated to have used the correct type for rendering, which guarantees that they match the declaration. This means you have to use the types to render complex responses, and manually building a Hash that conforms to the schema will raise an error. Primitive/scalar types are an exception, e.g. you *can* do:
|
@@ -244,6 +252,27 @@ class ErrorType < ObjectType
|
|
244
252
|
end
|
245
253
|
```
|
246
254
|
|
255
|
+
### Caching
|
256
|
+
|
257
|
+
Taro provides support for caching. The cache instance can be configured by setting `Taro::Cache.cache_instance`. By default, the railtie will set it to `Rails.cache`.
|
258
|
+
|
259
|
+
It supports configuring an ad hoc cache when using a render call, e.g.
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
bike = Bike.find(params[:id])
|
263
|
+
BikeType.with_cache(cache_key: bike.cache_key, expires_in: 3.minutes).render(bike)
|
264
|
+
```
|
265
|
+
|
266
|
+
Or by configuring the cache rule on a per type basis, e.g.
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
class BikeType < ObjectType
|
270
|
+
self.cache_key = ->(bike) { bike.cache_key_with_version }
|
271
|
+
self.expires_in = 1.hour
|
272
|
+
# ...
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
247
276
|
## FAQ
|
248
277
|
|
249
278
|
### How do I render API docs?
|
@@ -344,33 +373,8 @@ class MyController < ApplicationController
|
|
344
373
|
end
|
345
374
|
```
|
346
375
|
|
347
|
-
## Caching
|
348
|
-
|
349
|
-
Taro provides support for caching. The cache instance can be configured by setting `Taro::Cache.cache_instance`. By default, the railtie will set it to `Rails.cache`.
|
350
|
-
|
351
|
-
It supports configuring an add hoc cache when using a render call, e.g.
|
352
|
-
|
353
|
-
```ruby
|
354
|
-
bike = Bike.find(params[:id])
|
355
|
-
BikeType.with_cache(cache_key: bike.cache_key, expires_in: 3.minutes).render(bike)
|
356
|
-
```
|
357
|
-
|
358
|
-
Or by configuring the cache rule on a per type bases, e.g.
|
359
|
-
|
360
|
-
```ruby
|
361
|
-
class BikeType < ObjectType
|
362
|
-
# Optional description of BikeType (for the OpenAPI export)
|
363
|
-
self.desc = 'A bike and all relevant information about it'
|
364
|
-
self.cache_key = ->(bike) { bike.cache_key_with_version }
|
365
|
-
self.expires_in = 1.hour
|
366
|
-
|
367
|
-
...
|
368
|
-
end
|
369
|
-
```
|
370
|
-
|
371
376
|
## Possible future features
|
372
377
|
|
373
|
-
- warning/raising for undeclared input params (currently they are ignored)
|
374
378
|
- usage without rails is possible but not convenient yet
|
375
379
|
- rspec matchers for testing
|
376
380
|
- sum types
|
data/lib/taro/config.rb
CHANGED
@@ -5,6 +5,7 @@ module Taro::Config
|
|
5
5
|
:export_format,
|
6
6
|
:export_path,
|
7
7
|
:parse_params,
|
8
|
+
:raise_for_undeclared_params,
|
8
9
|
:validate_response,
|
9
10
|
)
|
10
11
|
|
@@ -14,6 +15,7 @@ module Taro::Config
|
|
14
15
|
self.export_format = :yaml
|
15
16
|
self.export_path = 'api.yml'
|
16
17
|
self.parse_params = true
|
18
|
+
self.raise_for_undeclared_params = false # may be overridden by railtie
|
17
19
|
self.validate_response = true
|
18
20
|
end
|
19
21
|
|
data/lib/taro/declaration.rb
CHANGED
@@ -5,7 +5,7 @@ class Taro::Declaration
|
|
5
5
|
attr_reader :desc, :summary, :params, :return_defs, :return_descriptions, :tags
|
6
6
|
|
7
7
|
def initialize(for_klass = nil)
|
8
|
-
@params = Class.new(Taro::Types::
|
8
|
+
@params = Class.new(Taro::Types::RailsParamsType)
|
9
9
|
@return_defs = {}
|
10
10
|
@return_descriptions = {}
|
11
11
|
|
data/lib/taro/rails/railtie.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class Taro::Rails::Railtie < ::Rails::Railtie
|
2
2
|
initializer("taro") do |app|
|
3
|
+
Taro.config.raise_for_undeclared_params = %w[development test].include?(Rails.env)
|
4
|
+
|
3
5
|
# The `:action_controller` hook fires for both ActionController::API
|
4
6
|
# and ActionController::Base, executing the block in their context.
|
5
7
|
ActiveSupport.on_load(:action_controller) do
|
data/lib/taro/types/base_type.rb
CHANGED
data/lib/taro/types/field.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative 'field_validation'
|
|
3
3
|
Taro::Types::Field = Data.define(:name, :type, :null, :method, :default, :enum, :defined_at, :desc, :deprecated) do
|
4
4
|
include Taro::Types::FieldValidation
|
5
5
|
include Taro::Types::Shared::Errors
|
6
|
+
include Taro::Types::Shared::TypeClass
|
6
7
|
|
7
8
|
def initialize(name:, type:, null:, method: name, default: Taro::None, enum: nil, defined_at: nil, desc: nil, deprecated: nil)
|
8
9
|
enum = coerce_to_enum(enum)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'object_type'
|
2
|
+
|
3
|
+
# Abstract base class for rails declaration params. Internal use only.
|
4
|
+
class Taro::Types::RailsParamsType < Taro::Types::InputType
|
5
|
+
# Skip validation of base params because they contain rails "additions"
|
6
|
+
# like controller, action, routing-related stuff, de-nested values, etc.
|
7
|
+
def validate_no_undeclared_params?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
end
|
@@ -7,7 +7,7 @@ module Taro::Types::Shared::Caching
|
|
7
7
|
|
8
8
|
def self.included(klass)
|
9
9
|
klass.extend(ClassMethods)
|
10
|
-
klass.singleton_class.attr_accessor :expires_in
|
10
|
+
klass.singleton_class.attr_accessor :expires_in
|
11
11
|
klass.singleton_class.attr_reader :cache_key
|
12
12
|
end
|
13
13
|
|
@@ -23,7 +23,8 @@ module Taro::Types::Shared::Caching
|
|
23
23
|
klass = dup
|
24
24
|
klass.cache_key = cache_key.is_a?(Proc) ? cache_key : ->(_) { cache_key }
|
25
25
|
klass.expires_in = expires_in
|
26
|
-
|
26
|
+
this = self
|
27
|
+
klass.define_singleton_method(:type_class) { this }
|
27
28
|
klass
|
28
29
|
end
|
29
30
|
end
|
@@ -35,9 +35,11 @@ module Taro::Types::Shared::DerivedTypes
|
|
35
35
|
|
36
36
|
root.define_singleton_method(method_name) do
|
37
37
|
derived_types[type] ||= begin
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
name || raise(Taro::ArgumentError, 'Cannot derive from anonymous type')
|
39
|
+
|
40
|
+
coerced_type = Taro::Types::Coercion.call(type:)
|
41
|
+
new_type = Class.new(coerced_type)
|
42
|
+
new_type.define_name("#{name}.#{method_name}")
|
41
43
|
new_type.derive_from(self)
|
42
44
|
new_type
|
43
45
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# Provides input and response handling for types with fields.
|
2
2
|
module Taro::Types::Shared::ObjectCoercion
|
3
3
|
def coerce_input
|
4
|
+
validate_no_undeclared_params
|
4
5
|
self.class.fields.transform_values do |field|
|
5
6
|
field.value_for_input(object)
|
6
7
|
end
|
@@ -13,4 +14,17 @@ module Taro::Types::Shared::ObjectCoercion
|
|
13
14
|
field.value_for_response(object, context: self, object_is_hash:)
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def validate_no_undeclared_params
|
21
|
+
return unless validate_no_undeclared_params?
|
22
|
+
|
23
|
+
undeclared = object.to_h.keys.map(&:to_sym) - self.class.send(:field_defs).keys
|
24
|
+
undeclared.any? && input_error("Undeclared params: #{undeclared.join(', ')}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_no_undeclared_params?
|
28
|
+
Taro.config.raise_for_undeclared_params
|
29
|
+
end
|
16
30
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Taro::Types::Shared::Rendering
|
2
2
|
# The `::render` method is intended for use in controllers.
|
3
3
|
# Overrides of this method must call super.
|
4
|
-
def render(object
|
5
|
-
result =
|
6
|
-
|
7
|
-
end
|
8
|
-
self.last_render = [self.without_cache || self, result.__id__]
|
4
|
+
def render(object)
|
5
|
+
result = new(object).cached_coerce_response
|
6
|
+
self.last_render = [type_class, result.__id__]
|
9
7
|
result
|
10
8
|
end
|
11
9
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# `type_class` is a convenience method to get the type class of types,
|
2
|
+
# of with_cache-types, of type instances, and of fields in the same way.
|
3
|
+
module Taro::Types::Shared::TypeClass
|
4
|
+
def self.included(klass)
|
5
|
+
if klass.instance_methods.include?(:type) # Field
|
6
|
+
klass.alias_method :type_class, :type
|
7
|
+
else # BaseType
|
8
|
+
klass.singleton_class.alias_method :type_class, :itself
|
9
|
+
klass.alias_method :type_class, :class
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/taro/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janosch Müller
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-02-
|
12
|
+
date: 2025-02-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/taro/types/object_types/no_content_type.rb
|
90
90
|
- lib/taro/types/object_types/page_info_type.rb
|
91
91
|
- lib/taro/types/object_types/page_type.rb
|
92
|
+
- lib/taro/types/rails_params_type.rb
|
92
93
|
- lib/taro/types/response_type.rb
|
93
94
|
- lib/taro/types/scalar/boolean_type.rb
|
94
95
|
- lib/taro/types/scalar/float_type.rb
|
@@ -117,6 +118,7 @@ files:
|
|
117
118
|
- lib/taro/types/shared/openapi_type.rb
|
118
119
|
- lib/taro/types/shared/pattern.rb
|
119
120
|
- lib/taro/types/shared/rendering.rb
|
121
|
+
- lib/taro/types/shared/type_class.rb
|
120
122
|
- lib/taro/version.rb
|
121
123
|
- tasks/benchmark.rake
|
122
124
|
- tasks/benchmark_1kb.json
|
@@ -143,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
145
|
- !ruby/object:Gem::Version
|
144
146
|
version: '0'
|
145
147
|
requirements: []
|
146
|
-
rubygems_version: 3.5.
|
148
|
+
rubygems_version: 3.5.22
|
147
149
|
signing_key:
|
148
150
|
specification_version: 4
|
149
151
|
summary: Typed Api using Ruby Objects.
|