ree_lib 1.0.36 → 1.0.38

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +9 -2
  3. data/lib/ree_lib/Packages.schema.json +8 -0
  4. data/lib/ree_lib/packages/ree_actions/.gitignore +0 -0
  5. data/lib/ree_lib/packages/ree_actions/.rspec +2 -0
  6. data/lib/ree_lib/packages/ree_actions/Package.schema.json +20 -0
  7. data/lib/ree_lib/packages/ree_actions/bin/console +5 -0
  8. data/lib/ree_lib/packages/ree_actions/package/ree_actions/action.rb +10 -0
  9. data/lib/ree_lib/packages/ree_actions/package/ree_actions/action_builder.rb +65 -0
  10. data/lib/ree_lib/packages/ree_actions/package/ree_actions/action_dsl.rb +60 -0
  11. data/lib/ree_lib/packages/ree_actions/package/ree_actions/dsl.rb +102 -0
  12. data/lib/ree_lib/packages/ree_actions/package/ree_actions.rb +12 -0
  13. data/lib/ree_lib/packages/ree_actions/spec/package_schema_spec.rb +14 -0
  14. data/lib/ree_lib/packages/ree_actions/spec/ree_actions/action_dsl_spec.rb +62 -0
  15. data/lib/ree_lib/packages/ree_actions/spec/ree_actions/dsl_spec.rb +93 -0
  16. data/lib/ree_lib/packages/ree_actions/spec/spec_helper.rb +3 -0
  17. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/functions/build_mapper_factory.rb +4 -0
  18. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +17 -10
  19. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb +73 -35
  20. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/any.rb +23 -0
  21. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/wrappers/abstract_wrapper.rb +8 -0
  22. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/{types → wrappers}/array.rb +10 -17
  23. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper.rb +5 -1
  24. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +62 -2
  25. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/any_spec.rb +47 -0
  26. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/type_options_spec.rb +4 -4
  27. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/{types → wrappers}/array_spec.rb +7 -7
  28. data/lib/ree_lib/packages/ree_roda/.gitignore +0 -0
  29. data/lib/ree_lib/packages/ree_roda/.rspec +2 -0
  30. data/lib/ree_lib/packages/ree_roda/Package.schema.json +58 -0
  31. data/lib/ree_lib/packages/ree_roda/bin/console +5 -0
  32. data/lib/ree_lib/packages/ree_roda/package/ree_roda/app.rb +46 -0
  33. data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_actions.rb +150 -0
  34. data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_logger.rb +66 -0
  35. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_action_errors.rb +76 -0
  36. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_swagger_from_actions.rb +55 -0
  37. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/status_from_error.rb +25 -0
  38. data/lib/ree_lib/packages/ree_roda/package/ree_roda.rb +19 -0
  39. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_action_errors.schema.json +28 -0
  40. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_swagger_from_actions.schema.json +63 -0
  41. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/status_from_error.schema.json +28 -0
  42. data/lib/ree_lib/packages/ree_roda/spec/package_schema_spec.rb +14 -0
  43. data/lib/ree_lib/packages/ree_roda/spec/ree_roda/app_spec.rb +84 -0
  44. data/lib/ree_lib/packages/ree_roda/spec/spec_helper.rb +3 -0
  45. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/beans/type_definitions_repo.rb +1 -1
  46. data/lib/ree_lib/packages/ree_swagger/spec/functions/build_parameters_spec.rb +1 -1
  47. data/lib/ree_lib/packages/ree_swagger/spec/functions/build_serializer_schema_spec.rb +3 -3
  48. data/lib/ree_lib/version.rb +1 -1
  49. metadata +65 -4
@@ -0,0 +1,150 @@
1
+ class Roda
2
+ module RodaPlugins
3
+ module ReeActions
4
+ def self.load_dependencies(app, opts = {})
5
+ package_require("ree_roda/services/build_swagger_from_actions")
6
+ package_require("ree_json/functions/to_json")
7
+ package_require("ree_hash/functions/transform_values")
8
+ package_require("ree_object/functions/not_blank")
9
+
10
+ app.plugin :all_verbs
11
+ end
12
+
13
+ def self.configure(app, opts = {})
14
+ app.opts[:ree_actions_before] = opts[:before] if opts[:before]
15
+ end
16
+
17
+ module ClassMethods
18
+ def ree_actions(actions, swagger_title: "", swagger_description: "",
19
+ swagger_version: "", swagger_url: "", api_url: "")
20
+ @ree_actions ||= []
21
+ @ree_actions += actions
22
+
23
+ opts[:ree_actions_swagger_title] = swagger_title
24
+ opts[:ree_actions_swagger_description] = swagger_description
25
+ opts[:ree_actions_swagger_version] = swagger_version
26
+ opts[:ree_actions_swagger_url] = swagger_url
27
+ opts[:ree_actions_api_url] = api_url
28
+
29
+ opts[:ree_actions_swagger] = ReeRoda::BuildSwaggerFromActions.new.call(
30
+ @ree_actions,
31
+ opts[:ree_actions_swagger_title],
32
+ opts[:ree_actions_swagger_description],
33
+ opts[:ree_actions_swagger_version],
34
+ opts[:ree_actions_api_url]
35
+ )
36
+
37
+ build_actions_proc
38
+ nil
39
+ end
40
+
41
+ private
42
+
43
+ def build_actions_proc
44
+ list = []
45
+ context = self
46
+
47
+ return list if @ree_actions.nil? || @ree_actions.empty?
48
+
49
+ if context.opts[:ree_actions_swagger_url]
50
+ list << Proc.new do |r|
51
+ r.get context.opts[:ree_actions_swagger_url] do
52
+ r.json do
53
+ response.status = 200
54
+ ReeJson::ToJson.new.call(context.opts[:ree_actions_swagger])
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ @ree_actions.each do |action|
61
+ route = []
62
+ route_args = []
63
+
64
+ action.path.split("/").each do |part|
65
+ if part.start_with?(":")
66
+ route << String
67
+ route_args << part.gsub(":", "")
68
+ else
69
+ route << part
70
+ end
71
+ end
72
+
73
+ list << Proc.new do |r|
74
+ r.send(action.request_method, *route) do |*args|
75
+ r.send(action.respond_to) do
76
+ env["warden"].authenticate!(scope: action.warden_scope)
77
+
78
+ if context.opts[:ree_actions_before]
79
+ self.instance_exec(@_request, action.warden_scope, &scope.opts[:ree_actions_before])
80
+ end
81
+
82
+ # TODO: implement me when migration to roda DSL happens
83
+ # if action.before; end
84
+
85
+ route_args.each_with_index do |arg, index|
86
+ r.params["#{arg}"] = args[index]
87
+ end
88
+
89
+ params = r.params
90
+
91
+ if r.body
92
+ body = begin
93
+ JSON.parse(r.body.read)
94
+ rescue => e
95
+ {}
96
+ end
97
+
98
+ params = params.merge(body)
99
+ end
100
+
101
+ not_blank = ReeObject::NotBlank.new
102
+
103
+ filtered_params = ReeHash::TransformValues.new.call(params) do |k, v|
104
+ v.is_a?(Array) ? v.select { not_blank.call(_1) } : v
105
+ end
106
+
107
+ accessor = env["warden"].user(action.warden_scope)
108
+ action_result = action.action.klass.new.call(accessor, filtered_params)
109
+
110
+ if action.serializer
111
+ serialized_result = action.serializer.klass.new.serialize(action_result)
112
+ else
113
+ serialized_result = {}
114
+ end
115
+
116
+ case action.request_method
117
+ when :post
118
+ response.status = 201
119
+ ReeJson::ToJson.new.call(serialized_result)
120
+ when :put, :delete, :patch
121
+ response.status = 204
122
+ ""
123
+ else
124
+ response.status = 200
125
+ ReeJson::ToJson.new.call(serialized_result)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ opts[:ree_actions_proc] = list
133
+ end
134
+ end
135
+
136
+ module RequestMethods
137
+ def ree_actions
138
+ if scope.opts[:ree_actions_proc]
139
+ scope.opts[:ree_actions_proc].each do |request_proc|
140
+ self.instance_exec(self, &request_proc)
141
+ end
142
+ end
143
+ nil
144
+ end
145
+ end
146
+ end
147
+
148
+ register_plugin(:ree_actions, Roda::RodaPlugins::ReeActions)
149
+ end
150
+ end
@@ -0,0 +1,66 @@
1
+ package_require "ree_logger/beans/logger"
2
+
3
+ class Roda
4
+ module RodaPlugins
5
+ # The ree_logger plugin adds ReeLogger support to Roda
6
+ #
7
+ # Example:
8
+ #
9
+ # plugin :ree_logger
10
+ # plugin :ree_logger, log_params: true, filter: -> { request.path.include?("health") }
11
+ module ReeLogger
12
+ REE_LOGGER_DEFAULTS = {
13
+ method: :info,
14
+ log_params: true
15
+ }
16
+
17
+ def self.configure(app, **opts)
18
+ opts = REE_LOGGER_DEFAULTS.merge(opts)
19
+ app.opts[:ree_logger] = ::ReeLogger::Logger.new
20
+ app.opts[:ree_logger_filter] = opts[:filter] if opts[:filter]
21
+ app.opts[:ree_logger_log_params] = !!opts[:log_params]
22
+ end
23
+
24
+ def self.start_timer
25
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
26
+ end
27
+
28
+ module InstanceMethods
29
+ private
30
+
31
+ # Log request/response information in common log format to logger.
32
+ def _roda_after_90__ree_logger(result)
33
+ return unless result && result[0] && result[1]
34
+
35
+ if opts[:ree_logger_filter]
36
+ return if self.instance_exec(&opts[:ree_logger_filter])
37
+ end
38
+
39
+ elapsed_time = if timer = @_request_timer
40
+ "%0.4f" % (ReeLogger.start_timer - timer)
41
+ else
42
+ "-"
43
+ end
44
+
45
+ env = @_request.env
46
+
47
+ message = <<~DOC
48
+ Request/Response details:
49
+ Request: #{env["REQUEST_METHOD"]} #{env["QUERY_STRING"] && !env["QUERY_STRING"].empty? ? env["SCRIPT_NAME"].to_s + env["PATH_INFO"] + "?#{env["QUERY_STRING"]}": env["SCRIPT_NAME"].to_s + env["PATH_INFO"]} #{opts[:ree_logger_log_params] ? "\n Params: " + request.params.inspect : ""}
50
+ Response status: #{response.status || "-"}#{(400..499).include?(response.status) ? "\n Response body: " + response.body[0] : ""}
51
+ Time Taken: #{elapsed_time}
52
+ DOC
53
+
54
+ opts[:ree_logger].info(message)
55
+ end
56
+
57
+ # Create timer instance used for timing
58
+ def _roda_before_05__ree_logger
59
+ @_request_timer = ReeLogger.start_timer
60
+ end
61
+ end
62
+ end
63
+
64
+ register_plugin(:ree_logger, ReeLogger)
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ class ReeRoda::BuildActionErrors
2
+ include Ree::FnDSL
3
+
4
+ fn :build_action_errors do
5
+ link "ree_swagger/dto/error_dto", -> { ErrorDto }
6
+ end
7
+
8
+ contract(ReeActions::Action => ArrayOf[ErrorDto])
9
+ def call(action)
10
+ ree_object = action.action
11
+ errors = recursively_extract_errors(ree_object)
12
+
13
+ errors
14
+ .select {
15
+ _1.ancestors.include?(ReeErrors::Error) && status_from_error(_1)
16
+ }
17
+ .map {
18
+ e = _1.new
19
+ description = "type: **#{e.type}**, code: **#{e.code}**, message: **#{e.message}**"
20
+
21
+ ErrorDto.new(
22
+ status: status_from_error(_1),
23
+ description: description
24
+ )
25
+ }
26
+ .uniq { [_1.status, _1.description] }
27
+ end
28
+
29
+ private
30
+
31
+ def recursively_extract_errors(ree_object)
32
+ errors = extract_errors(ree_object)
33
+
34
+ ree_object.links.each do |link|
35
+ obj = Ree.container.packages_facade.get_object(
36
+ link.package_name, link.object_name
37
+ )
38
+
39
+ if obj.fn?
40
+ errors += recursively_extract_errors(obj)
41
+ end
42
+ end
43
+
44
+ errors
45
+ end
46
+
47
+ def extract_errors(ree_object)
48
+ klass = ree_object.klass
49
+ return [] if ree_object.object?
50
+
51
+ method_decorator = Ree::Contracts.get_method_decorator(
52
+ klass, :call, scope: :instance
53
+ )
54
+
55
+ method_decorator&.errors || []
56
+ end
57
+
58
+ def status_from_error(error)
59
+ case error.instance_variable_get(:@type)
60
+ when :not_found
61
+ 404
62
+ when :invalid_param
63
+ 400
64
+ when :conflict
65
+ 405
66
+ when :auth
67
+ 401
68
+ when :permission
69
+ 403
70
+ when :payment
71
+ 402
72
+ when :validation
73
+ 422
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,55 @@
1
+ class ReeRoda::BuildSwaggerFromActions
2
+ include Ree::FnDSL
3
+
4
+ fn :build_swagger_from_actions do
5
+ link :build_action_errors
6
+ link :build_schema, from: :ree_swagger
7
+ link "ree_swagger/dto/endpoint_dto", -> { EndpointDto }
8
+ end
9
+
10
+ contract(ArrayOf[ReeActions::Action], String, String, String, String => Hash)
11
+ def call(actions, title, description, version, api_url)
12
+ endpoints = actions.map do |action|
13
+ method_decorator = Ree::Contracts.get_method_decorator(
14
+ action.action.klass, :call, scope: :instance
15
+ )
16
+
17
+ response_status = case action.request_method
18
+ when :post
19
+ 201
20
+ when :put, :delete, :patch
21
+ 204
22
+ else
23
+ 200
24
+ end
25
+
26
+ caster = if action.action.klass.const_defined?(:ActionCaster)
27
+ action.action.klass.const_get(:ActionCaster)
28
+ end
29
+
30
+ EndpointDto.new(
31
+ method: action.request_method,
32
+ sections: action.sections,
33
+ respond_to: action.respond_to,
34
+ path: action.path.start_with?("/") ? action.path : "/#{action.path}",
35
+ caster: caster,
36
+ serializer: action.serializer&.klass&.new,
37
+ summary: action.summary,
38
+ authenticate: action.warden_scope != :visitor,
39
+ description: method_decorator&.doc || "",
40
+ response_status: response_status,
41
+ response_description: nil,
42
+ errors: build_action_errors(action)
43
+ )
44
+ end
45
+
46
+ build_schema(
47
+ title: title,
48
+ description: description,
49
+ version: version,
50
+ api_url: api_url,
51
+ endpoints: endpoints
52
+ )
53
+ end
54
+ end
55
+
@@ -0,0 +1,25 @@
1
+ class ReeRoda::StatusFromError
2
+ include Ree::FnDSL
3
+
4
+ fn :status_from_error
5
+
6
+ contract(Symbol => Nilor[Integer])
7
+ def call(error_type)
8
+ case error_type
9
+ when :not_found
10
+ 404
11
+ when :invalid_param
12
+ 400
13
+ when :conflict
14
+ 405
15
+ when :auth
16
+ 401
17
+ when :permission
18
+ 403
19
+ when :payment
20
+ 402
21
+ when :validation
22
+ 422
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ require "roda"
2
+
3
+ module ReeRoda
4
+ include Ree::PackageDSL
5
+
6
+ package do
7
+ depends_on :ree_actions
8
+ depends_on :ree_logger
9
+ depends_on :ree_json
10
+ depends_on :ree_hash
11
+ depends_on :ree_object
12
+ depends_on :ree_swagger
13
+ depends_on :ree_errors
14
+ end
15
+ end
16
+
17
+ package_require "ree_roda/plugins/ree_logger"
18
+ package_require "ree_roda/plugins/ree_actions"
19
+ package_require "ree_roda/app"
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_type": "object",
3
+ "schema_version": "1.1",
4
+ "name": "build_action_errors",
5
+ "path": "packages/ree_roda/package/ree_roda/services/build_action_errors.rb",
6
+ "mount_as": "fn",
7
+ "class": "ReeRoda::BuildActionErrors",
8
+ "factory": null,
9
+ "methods": [
10
+ {
11
+ "doc": "",
12
+ "throws": [
13
+
14
+ ],
15
+ "return": "ArrayOf[ReeSwagger::ErrorDto]",
16
+ "args": [
17
+ {
18
+ "arg": "action",
19
+ "arg_type": "req",
20
+ "type": "ReeActions::Action"
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "links": [
26
+
27
+ ]
28
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "schema_type": "object",
3
+ "schema_version": "1.1",
4
+ "name": "build_swagger_from_actions",
5
+ "path": "packages/ree_roda/package/ree_roda/services/build_swagger_from_actions.rb",
6
+ "mount_as": "fn",
7
+ "class": "ReeRoda::BuildSwaggerFromActions",
8
+ "factory": null,
9
+ "methods": [
10
+ {
11
+ "doc": "",
12
+ "throws": [
13
+
14
+ ],
15
+ "return": "Hash",
16
+ "args": [
17
+ {
18
+ "arg": "actions",
19
+ "arg_type": "req",
20
+ "type": "ArrayOf[ReeActions::Action]"
21
+ },
22
+ {
23
+ "arg": "title",
24
+ "arg_type": "req",
25
+ "type": "String"
26
+ },
27
+ {
28
+ "arg": "description",
29
+ "arg_type": "req",
30
+ "type": "String"
31
+ },
32
+ {
33
+ "arg": "version",
34
+ "arg_type": "req",
35
+ "type": "String"
36
+ },
37
+ {
38
+ "arg": "api_url",
39
+ "arg_type": "req",
40
+ "type": "String"
41
+ }
42
+ ]
43
+ }
44
+ ],
45
+ "links": [
46
+ {
47
+ "target": "build_action_errors",
48
+ "package_name": "ree_roda",
49
+ "as": "build_action_errors",
50
+ "imports": [
51
+
52
+ ]
53
+ },
54
+ {
55
+ "target": "build_schema",
56
+ "package_name": "ree_swagger",
57
+ "as": "build_schema",
58
+ "imports": [
59
+
60
+ ]
61
+ }
62
+ ]
63
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_type": "object",
3
+ "schema_version": "1.1",
4
+ "name": "status_from_error",
5
+ "path": "packages/ree_roda/package/ree_roda/services/status_from_error.rb",
6
+ "mount_as": "fn",
7
+ "class": "ReeRoda::StatusFromError",
8
+ "factory": null,
9
+ "methods": [
10
+ {
11
+ "doc": "",
12
+ "throws": [
13
+
14
+ ],
15
+ "return": "Nilor[Integer]",
16
+ "args": [
17
+ {
18
+ "arg": "error_type",
19
+ "arg_type": "req",
20
+ "type": "Symbol"
21
+ }
22
+ ]
23
+ }
24
+ ],
25
+ "links": [
26
+
27
+ ]
28
+ }
@@ -0,0 +1,14 @@
1
+ RSpec.describe "ReeRoda" do
2
+ it "generates package schema" do
3
+ require "fileutils"
4
+
5
+ packages_schema_path = Ree.locate_packages_schema(__dir__)
6
+ packages_schema_dir = Pathname.new(packages_schema_path).dirname.to_s
7
+
8
+ FileUtils.cd packages_schema_dir do
9
+ expect(
10
+ system("REE_SKIP_ENV_VARS_CHECK=true bundle exec ree gen.package_json ree_roda --silence")
11
+ ).to eq(true)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,84 @@
1
+ require "rack/test"
2
+
3
+ package_require("ree_roda/app")
4
+ package_require("ree_actions/dsl")
5
+ package_require("ree_roda/plugins/ree_actions")
6
+
7
+ RSpec.describe ReeRoda::App do
8
+ include Rack::Test::Methods
9
+
10
+ before :all do
11
+ Ree.enable_irb_mode
12
+
13
+ module ReeRodaTest
14
+ include Ree::PackageDSL
15
+
16
+ package
17
+ end
18
+
19
+ class ReeRodaTest::Cmd
20
+ include ReeActions::ActionDSL
21
+
22
+ action :cmd
23
+
24
+ ActionCaster = build_mapper.use(:cast) do
25
+ integer :id
26
+ end
27
+
28
+ def call(access, attrs)
29
+ end
30
+ end
31
+
32
+ class ReeRodaTest::TestActions
33
+ include ReeActions::DSL
34
+
35
+ actions :test_actions do
36
+ default_warden_scope :identity
37
+ opts = {from: :ree_roda_test}
38
+
39
+ get "api/action/:id" do
40
+ summary "Some action"
41
+ warden_scope :visitor
42
+ sections "some_action"
43
+ action :cmd, **opts
44
+ end
45
+ end
46
+ end
47
+
48
+ class TestApp < ReeRoda::App
49
+ plugin :ree_actions
50
+
51
+ ree_actions ReeRodaTest::TestActions.new,
52
+ api_url: "http://some.api.url:1337",
53
+ swagger_url: "swagger"
54
+
55
+ route do |r|
56
+ r.get "health" do
57
+ "success"
58
+ end
59
+
60
+ r.ree_actions
61
+ end
62
+ end
63
+ end
64
+
65
+ after :all do
66
+ Ree.disable_irb_mode
67
+ end
68
+
69
+ let(:app) { TestApp.app }
70
+
71
+ it {
72
+ get "health"
73
+ expect(last_response.body).to eq("success")
74
+ expect(last_response.status).to eq(200)
75
+ }
76
+
77
+ it {
78
+ get "swagger"
79
+ expect(last_response.status).to eq(200)
80
+
81
+ get "api/v1/swagger"
82
+ expect(last_response.status).to eq(404)
83
+ }
84
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.extend Ree::RSpecLinkDSL
3
+ end
@@ -27,7 +27,7 @@ class ReeSwagger::TypeDefinitionsRepo
27
27
  ReeMapper::Array => ->(type, build_serializer_schema) {
28
28
  {
29
29
  type: 'array',
30
- items: build_serializer_schema.(type.of.type)
30
+ items: build_serializer_schema.(type.subject.type)
31
31
  }
32
32
  },
33
33
  ReeMapper::DateTime => ->(*) {
@@ -30,7 +30,7 @@ RSpec.describe :build_parameters_spec do
30
30
 
31
31
  it {
32
32
  caster = mapper_factory.call.use(:cast) do
33
- array :id, each: string
33
+ array :id, string
34
34
  end
35
35
 
36
36
  expect {
@@ -39,17 +39,17 @@ RSpec.describe :build_serializer_schema do
39
39
  end
40
40
 
41
41
  mapper_factory.call.use(:serialize) do
42
- integer :id, doc: 'Identificator'
42
+ integer :id, doc: 'Identificator'
43
43
  string :name
44
44
  bool :is_admin
45
45
  float :free_space
46
- array :tags, each: string
46
+ array :tags, string
47
47
  date_time :created_at
48
48
  date :birth_day
49
49
  time :updated_at
50
50
 
51
51
  setting :one_setting
52
- array :many_settings, each: setting
52
+ array :many_settings, setting
53
53
 
54
54
  hash :cart do
55
55
  integer :size
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.36"
4
+ VERSION = "1.0.38"
5
5
  end