ree_lib 1.0.36 → 1.0.38

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 (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
@@ -2,7 +2,7 @@
2
2
 
3
3
  class ReeMapper::MapperFactory
4
4
  class << self
5
- attr_reader :types, :strategies
5
+ attr_reader :types, :strategies, :wrappers
6
6
  end
7
7
 
8
8
  contract(Symbol => Nilor[ReeMapper::MapperStrategy])
@@ -18,9 +18,9 @@ class ReeMapper::MapperFactory
18
18
  )
19
19
  end
20
20
 
21
- contract(Symbol, ReeMapper::Mapper => Class).throws(ArgumentError)
21
+ contract(Symbol, ReeMapper::Mapper => SubclassOf[self]).throws(ArgumentError)
22
22
  def self.register_mapper(name, type)
23
- raise ArgumentError, "name of mapper type should not end with `?`" if name.to_s.end_with?('?')
23
+ raise ArgumentError, "mapper registration name should not end with `?`" if name.to_s.end_with?('?')
24
24
 
25
25
  defined_strategy_method = types[name]&.flat_map(&:strategy_methods)&.detect { type.find_strategy(_1) }
26
26
  raise ArgumentError, "type :#{name} with `#{defined_strategy_method}` strategy already registered" if defined_strategy_method
@@ -35,7 +35,7 @@ class ReeMapper::MapperFactory
35
35
  class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
36
36
  def #{name}(field_name = nil, optional: false, **opts)
37
37
  raise ReeMapper::Error, "invalid DSL usage" unless @mapper
38
- raise ArgumentError, "array item can't be optional" if field_name.nil? && optional
38
+ raise ArgumentError, "wrapped item can't be optional" if field_name.nil? && optional
39
39
 
40
40
  type = self.class.types.fetch(:#{name}).detect { (@mapper.strategy_methods - _1.strategy_methods).empty? }
41
41
 
@@ -43,9 +43,11 @@ class ReeMapper::MapperFactory
43
43
  raise ReeMapper::UnsupportedTypeError, "type :#{name} should implement `\#{@mapper.strategy_methods.join(', ')}`"
44
44
  end
45
45
 
46
- return ReeMapper::Field.new(type, optional: optional, **opts) unless field_name
46
+ field = ReeMapper::Field.new(type, field_name, optional: optional, **opts)
47
47
 
48
- @mapper.add_field(type, field_name, optional: optional, **opts)
48
+ return field unless field_name
49
+
50
+ @mapper.add_field(field)
49
51
  end
50
52
 
51
53
  def #{name}?(field_name, **opts)
@@ -56,6 +58,68 @@ class ReeMapper::MapperFactory
56
58
  self
57
59
  end
58
60
 
61
+ contract(Symbol, SubclassOf[ReeMapper::AbstractWrapper] => SubclassOf[self])
62
+ def self.register_wrapper(name, wrapper)
63
+ raise ArgumentError, "wrapper registration name should not end with `?`" if name.to_s.end_with?('?')
64
+ raise ArgumentError, "method :#{name} already defined" if !wrappers.key?(name) && method_defined?(name)
65
+
66
+ wrappers[name] ||= []
67
+ wrappers[name] << wrapper
68
+
69
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
70
+ contract(
71
+ Nilor[Symbol, ReeMapper::Field],
72
+ Nilor[ReeMapper::Field],
73
+ Kwargs[optional: Bool, dto: Nilor[Class]],
74
+ Ksplat[RestKeys => Any],
75
+ Optblock => Nilor[ReeMapper::Field]
76
+ ).throws(ReeMapper::Error, ArgumentError, ReeMapper::UnsupportedTypeError)
77
+ def #{name}(field_name = nil, subject = nil, optional: false, dto: nil, **opts, &blk)
78
+ raise ReeMapper::Error, "invalid DSL usage" unless @mapper
79
+ raise ArgumentError, 'wrapped type does not permit :dto without :block' if dto && !blk
80
+
81
+ if field_name.is_a?(ReeMapper::Field)
82
+ raise ArgumentError, "field_name should be a Symbol" if subject
83
+
84
+ subject = field_name
85
+ field_name = nil
86
+ end
87
+
88
+ raise ArgumentError, "wrapped item can't be optional" if field_name.nil? && optional
89
+ raise ArgumentError, "wrapped type should use either :subject or :block" if subject && blk || !subject && !blk
90
+
91
+ if blk
92
+ subject = ReeMapper::Field.new(
93
+ hash_from_blk(dto: dto, &blk)
94
+ )
95
+ end
96
+
97
+ wrapper = self.class.wrappers.fetch(:#{name}).detect do |wrapper|
98
+ @mapper.strategy_methods.all? { wrapper.method_defined?(_1) }
99
+ end
100
+
101
+ unless wrapper
102
+ raise ReeMapper::UnsupportedTypeError, "wrapper :#{name} should implement `\#{@mapper.strategy_methods.join(', ')}`"
103
+ end
104
+
105
+ type = ReeMapper::Mapper.build(@mapper.strategies, wrapper.new(subject))
106
+ type.name = :#{name}
107
+
108
+ field = ReeMapper::Field.new(type, field_name, optional: optional, **opts)
109
+
110
+ return field unless field_name
111
+
112
+ @mapper.add_field(field)
113
+ end
114
+
115
+ def #{name}?(*args, **opts, &blk)
116
+ #{name}(*args, optional: true, **opts, &blk)
117
+ end
118
+ RUBY
119
+
120
+ self
121
+ end
122
+
59
123
  contract(
60
124
  Kwargs[
61
125
  register_as: Nilor[Symbol]
@@ -71,41 +135,15 @@ class ReeMapper::MapperFactory
71
135
  @mapper = mapper
72
136
  end
73
137
 
74
- contract(Nilor[Symbol], Kwargs[each: Nilor[ReeMapper::Field], optional: Bool, dto: Nilor[Class]], Ksplat[RestKeys => Any], Optblock => Nilor[ReeMapper::Field])
75
- def array(field_name = nil, each: nil, optional: false, dto: nil, **opts, &blk)
76
- raise ReeMapper::Error, "invalid DSL usage" unless @mapper
77
- raise ArgumentError, "array item can't be optional" if field_name.nil? && optional
78
- raise ArgumentError, 'array type should use either :each or :block' if each && blk || !each && !blk
79
- raise ArgumentError, 'array does not permit :dto without :block' if dto && !blk
80
- raise ArgumentError, 'array does not permit :only and :except keys' if opts.key?(:only) || opts.key?(:except)
81
-
82
- if blk
83
- each = ReeMapper::Field.new(
84
- hash_from_blk(dto: dto, &blk)
85
- )
86
- end
87
-
88
- type = ReeMapper::Mapper.build(@mapper.strategies, ReeMapper::Array.new(each))
89
-
90
- return ReeMapper::Field.new(type, optional: optional, **opts) unless field_name
91
-
92
- @mapper.add_field(type, field_name, optional: optional, **opts)
93
- end
94
-
95
- contract(Symbol, Kwargs[each: Nilor[ReeMapper::Field]], Ksplat[RestKeys => Any], Optblock => Nilor[ReeMapper::Field])
96
- def array?(field_name, each: nil, **opts, &blk)
97
- raise ArgumentError if opts.key?(:optional)
98
-
99
- array(field_name, each: each, optional: true, **opts, &blk)
100
- end
101
-
102
138
  contract(Symbol, Kwargs[dto: Nilor[Class]], Ksplat[RestKeys => Any], Block => nil)
103
139
  def hash(field_name, dto: nil, **opts, &blk)
104
140
  raise ReeMapper::Error, "invalid DSL usage" unless @mapper
105
141
 
106
142
  type = hash_from_blk(dto: dto, &blk)
107
143
 
108
- @mapper.add_field(type, field_name, **opts)
144
+ field = ReeMapper::Field.new(type, field_name, **opts)
145
+
146
+ @mapper.add_field(field)
109
147
  end
110
148
 
111
149
  contract(Symbol, Ksplat[RestKeys => Any], Block => nil)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReeMapper::Any < ReeMapper::AbstractType
4
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Any)
5
+ def serialize(value, name:, role: nil)
6
+ value
7
+ end
8
+
9
+ contract(Any , Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Any)
10
+ def cast(value, name:, role: nil)
11
+ value
12
+ end
13
+
14
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Any)
15
+ def db_dump(value, name:, role: nil)
16
+ value
17
+ end
18
+
19
+ contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]]] => Any)
20
+ def db_load(value, name:, role: nil)
21
+ value
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ class ReeMapper::AbstractWrapper
2
+ attr_reader :subject
3
+
4
+ contract ReeMapper::Field => Any
5
+ def initialize(field)
6
+ @subject = field
7
+ end
8
+ end
@@ -1,22 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class ReeMapper::Array < ReeMapper::AbstractType
4
- attr_reader :of
5
-
6
- contract ReeMapper::Field => Any
7
- def initialize(of)
8
- @of = of
9
- end
10
-
3
+ class ReeMapper::Array < ReeMapper::AbstractWrapper
11
4
  contract(Any, Kwargs[name: String, role: Nilor[Symbol, ArrayOf[Symbol]], fields_filters: ArrayOf[ReeMapper::FieldsFilter]] => Array)
12
5
  .throws(ReeMapper::TypeError)
13
6
  def serialize(value, name:, role: nil, fields_filters: [])
14
7
  if value.is_a?(Array)
15
8
  value.map.with_index {
16
- if _1.nil? && of.null
9
+ if _1.nil? && subject.null
17
10
  _1
18
11
  else
19
- of.type.serialize(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
12
+ subject.type.serialize(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [subject.fields_filter])
20
13
  end
21
14
  }
22
15
  else
@@ -29,10 +22,10 @@ class ReeMapper::Array < ReeMapper::AbstractType
29
22
  def cast(value, name:, role: nil, fields_filters: [])
30
23
  if value.is_a?(Array)
31
24
  value.map.with_index {
32
- if _1.nil? && of.null
25
+ if _1.nil? && subject.null
33
26
  _1
34
27
  else
35
- of.type.cast(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
28
+ subject.type.cast(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [subject.fields_filter])
36
29
  end
37
30
  }
38
31
  else
@@ -45,10 +38,10 @@ class ReeMapper::Array < ReeMapper::AbstractType
45
38
  def db_dump(value, name:, role: nil, fields_filters: [])
46
39
  if value.is_a?(Array)
47
40
  value.map.with_index {
48
- if _1.nil? && of.null
41
+ if _1.nil? && subject.null
49
42
  _1
50
43
  else
51
- of.type.db_dump(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
44
+ subject.type.db_dump(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [subject.fields_filter])
52
45
  end
53
46
  }
54
47
  else
@@ -61,14 +54,14 @@ class ReeMapper::Array < ReeMapper::AbstractType
61
54
  def db_load(value, name:, role: nil, fields_filters: [])
62
55
  if value.is_a?(Array)
63
56
  value.map.with_index {
64
- if _1.nil? && of.null
57
+ if _1.nil? && subject.null
65
58
  _1
66
59
  else
67
- of.type.db_load(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [of.fields_filter])
60
+ subject.type.db_load(_1, name: "#{name}[#{_2}]", role: role, fields_filters: fields_filters + [subject.fields_filter])
68
61
  end
69
62
  }
70
63
  else
71
64
  raise ReeMapper::TypeError, "`#{name}` should be an array"
72
65
  end
73
66
  end
74
- end
67
+ end
@@ -22,14 +22,18 @@ module ReeMapper
22
22
  require_relative 'ree_mapper/fields_filter'
23
23
  require_relative 'ree_mapper/field'
24
24
 
25
+
26
+ require_relative 'ree_mapper/wrappers/abstract_wrapper'
27
+ require_relative 'ree_mapper/wrappers/array'
28
+
25
29
  require_relative 'ree_mapper/types/bool'
30
+ require_relative 'ree_mapper/types/any'
26
31
  require_relative 'ree_mapper/types/date_time'
27
32
  require_relative 'ree_mapper/types/time'
28
33
  require_relative 'ree_mapper/types/date'
29
34
  require_relative 'ree_mapper/types/float'
30
35
  require_relative 'ree_mapper/types/integer'
31
36
  require_relative 'ree_mapper/types/string'
32
- require_relative 'ree_mapper/types/array'
33
37
 
34
38
  require_relative 'ree_mapper/strategy_outputs/strategy_output'
35
39
  require_relative 'ree_mapper/strategy_outputs/object_output'
@@ -43,7 +43,7 @@ RSpec.describe ReeMapper::MapperFactory do
43
43
  ).to eq({ val: { id: 1 } })
44
44
  }
45
45
 
46
- it 'allow to register caster and serializer with same name' do
46
+ it 'allow to register caster and serializer with the same name' do
47
47
  caster = mapper_factory.call.use(:cast) { string :name }
48
48
 
49
49
  mapper_factory.register_mapper(:new_type, serializer)
@@ -69,7 +69,7 @@ RSpec.describe ReeMapper::MapperFactory do
69
69
  it 'raise an error if the mapper name is ended by ?' do
70
70
  expect {
71
71
  mapper_factory.register_mapper(:new_type?, serializer)
72
- }.to raise_error(ArgumentError, 'name of mapper type should not end with `?`')
72
+ }.to raise_error(ArgumentError, 'mapper registration name should not end with `?`')
73
73
  end
74
74
 
75
75
  it 'raise an error if the mapper name is reserved' do
@@ -79,6 +79,66 @@ RSpec.describe ReeMapper::MapperFactory do
79
79
  end
80
80
  end
81
81
 
82
+ describe '.register_wrapper' do
83
+ let(:round_wrapper) {
84
+ Class.new(ReeMapper::AbstractWrapper) do
85
+ def serialize(value, name:, **opts)
86
+ raise ReeMapper::TypeError, "`#{name}` should be a number" if !value.is_a?(Numeric)
87
+
88
+ subject.type.serialize(value.round, name: name, **opts)
89
+ end
90
+ end
91
+ }
92
+
93
+ it {
94
+ mapper_factory.register_wrapper(:round, round_wrapper)
95
+
96
+ expect(
97
+ mapper_factory.call.use(:serialize) { round :val, integer }.serialize({ val: 1.1 })
98
+ ).to eq({ val: 1 })
99
+ }
100
+
101
+ it 'allow to register caster and serializer with the same name' do
102
+ caster_round_wrapper = Class.new(ReeMapper::AbstractWrapper) do
103
+ def cast(value, name:, **opts)
104
+ value = subject.type.cast(value, name: name, **opts)
105
+
106
+ raise ReeMapper::TypeError, "`#{name}` should be a number" if !value.is_a?(Numeric)
107
+ value.round
108
+ end
109
+ end
110
+
111
+ mapper_factory.register_wrapper(:round, round_wrapper)
112
+ mapper_factory.register_wrapper(:round, caster_round_wrapper)
113
+
114
+ expect(
115
+ mapper_factory.call.use(:serialize) { round :val, integer }.serialize({ val: 1.1 })
116
+ ).to eq({ val: 1 })
117
+
118
+ expect(
119
+ mapper_factory.call.use(:cast) { round :val, float }.cast({ val: '1.1' })
120
+ ).to eq({ val: 1 })
121
+ end
122
+
123
+ it 'raise an error if the registration wrapper name is ended by ?' do
124
+ expect {
125
+ mapper_factory.register_wrapper(:new_type?, round_wrapper)
126
+ }.to raise_error(ArgumentError, 'wrapper registration name should not end with `?`')
127
+ end
128
+
129
+ it 'raise an error if name is reserved' do
130
+ expect {
131
+ mapper_factory.register_wrapper(:hash, round_wrapper)
132
+ }.to raise_error(ArgumentError, 'method :hash already defined')
133
+ end
134
+
135
+ it 'raise an error if name is reserved by mapper' do
136
+ expect {
137
+ mapper_factory.register_wrapper(:integer, round_wrapper)
138
+ }.to raise_error(ArgumentError, 'method :integer already defined')
139
+ end
140
+ end
141
+
82
142
  describe '.use' do
83
143
  it {
84
144
  mapper = mapper_factory.call.use(:cast) do
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'ReeMapper::Bool' do
4
+ link :build_mapper_factory, from: :ree_mapper
5
+ link :build_mapper_strategy, from: :ree_mapper
6
+
7
+ let(:mapper_factory) {
8
+ build_mapper_factory(
9
+ strategies: [
10
+ build_mapper_strategy(method: :cast, dto: Hash),
11
+ build_mapper_strategy(method: :serialize, dto: Hash),
12
+ build_mapper_strategy(method: :db_dump, dto: Hash),
13
+ build_mapper_strategy(method: :db_load, dto: Hash)
14
+ ]
15
+ )
16
+ }
17
+
18
+ let(:mapper) {
19
+ mapper_factory.call.use(:cast).use(:serialize).use(:db_dump).use(:db_load) {
20
+ any :any
21
+ }
22
+ }
23
+
24
+ describe '#serialize' do
25
+ it {
26
+ expect(mapper.serialize({ any: true })).to eq({ any: true })
27
+ }
28
+ end
29
+
30
+ describe '#cast' do
31
+ it {
32
+ expect(mapper.cast({ 'any' => true })).to eq({ any: true })
33
+ }
34
+ end
35
+
36
+ describe '#db_dump' do
37
+ it {
38
+ expect(mapper.db_dump(OpenStruct.new({ any: true }))).to eq({ any: true })
39
+ }
40
+ end
41
+
42
+ describe '#db_load' do
43
+ it {
44
+ expect(mapper.db_load({ 'any' => true })).to eq({ any: true })
45
+ }
46
+ end
47
+ end
@@ -21,7 +21,7 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
21
21
  integer :x
22
22
  integer :y
23
23
  integer :z
24
- }
24
+ }
25
25
  }
26
26
 
27
27
  context 'with only' do
@@ -71,7 +71,7 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
71
71
  point :y, except: [:x, :z]
72
72
  end
73
73
 
74
- array :points, each: point(only: [:x, :y])
74
+ array :points, point(only: [:x, :y])
75
75
  }
76
76
  }
77
77
 
@@ -169,7 +169,7 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
169
169
  integer :number
170
170
  integer? :opt_number
171
171
  integer :opt_number_long, optional: true
172
- array? :opt_array, each: integer
172
+ array? :opt_array, integer
173
173
  array? :opt_array_with_blk do
174
174
  integer :id
175
175
  end
@@ -278,7 +278,7 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
278
278
  integer :for_all
279
279
  integer :for_admin, role: :admin
280
280
  }
281
-
281
+
282
282
  mapper_factory.call.use(:cast) {
283
283
  nested_type :my_field
284
284
  }
@@ -17,8 +17,8 @@ RSpec.describe 'ReeMapper::Array' do
17
17
 
18
18
  let(:mapper) {
19
19
  mapper_factory.call.use(:cast).use(:serialize).use(:db_dump).use(:db_load) {
20
- array :tags, each: integer
21
- array? :ary_of_ary, each: array(each: integer)
20
+ array :tags, integer
21
+ array? :ary_of_ary, array(integer)
22
22
  }
23
23
  }
24
24
 
@@ -73,7 +73,7 @@ RSpec.describe 'ReeMapper::Array' do
73
73
  context 'with array of array' do
74
74
  let(:mapper) {
75
75
  mapper_factory.call.use(:serialize) {
76
- array :coords, each: array(each: integer)
76
+ array :coords, array(integer)
77
77
  }
78
78
  }
79
79
 
@@ -85,7 +85,7 @@ RSpec.describe 'ReeMapper::Array' do
85
85
  context 'with nullable element of array' do
86
86
  let(:mapper) {
87
87
  mapper_factory.call.use(:serialize) {
88
- array :tags, each: integer(null: true)
88
+ array :tags, integer(null: true)
89
89
  }
90
90
  }
91
91
 
@@ -98,7 +98,7 @@ RSpec.describe 'ReeMapper::Array' do
98
98
  it {
99
99
  expect {
100
100
  mapper_factory.call.use(:serialize) {
101
- array :tags, each: integer?
101
+ array :tags, integer?
102
102
  }
103
103
  }.to raise_error(ArgumentError)
104
104
  }
@@ -106,7 +106,7 @@ RSpec.describe 'ReeMapper::Array' do
106
106
  it {
107
107
  expect {
108
108
  mapper_factory.call.use(:serialize) {
109
- array :tags, each: integer(optional: true)
109
+ array :tags, integer(optional: true)
110
110
  }
111
111
  }.to raise_error(ArgumentError)
112
112
  }
@@ -114,7 +114,7 @@ RSpec.describe 'ReeMapper::Array' do
114
114
  it {
115
115
  expect {
116
116
  mapper_factory.call.use(:serialize) {
117
- array :tags, each: array(each: integer, optional: true)
117
+ array :tags, array(integer, optional: true)
118
118
  }
119
119
  }.to raise_error(ArgumentError)
120
120
  }
File without changes
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,58 @@
1
+ {
2
+ "schema_type": "package",
3
+ "schema_version": "1.1",
4
+ "name": "ree_roda",
5
+ "entry_path": "packages/ree_roda/package/ree_roda.rb",
6
+ "tags": [
7
+ "ree_roda"
8
+ ],
9
+ "depends_on": [
10
+ {
11
+ "name": "ree_actions"
12
+ },
13
+ {
14
+ "name": "ree_errors"
15
+ },
16
+ {
17
+ "name": "ree_hash"
18
+ },
19
+ {
20
+ "name": "ree_json"
21
+ },
22
+ {
23
+ "name": "ree_logger"
24
+ },
25
+ {
26
+ "name": "ree_object"
27
+ },
28
+ {
29
+ "name": "ree_swagger"
30
+ }
31
+ ],
32
+ "env_vars": [
33
+
34
+ ],
35
+ "objects": [
36
+ {
37
+ "name": "build_action_errors",
38
+ "schema": "packages/ree_roda/schemas/ree_roda/services/build_action_errors.schema.json",
39
+ "tags": [
40
+ "fn"
41
+ ]
42
+ },
43
+ {
44
+ "name": "build_swagger_from_actions",
45
+ "schema": "packages/ree_roda/schemas/ree_roda/services/build_swagger_from_actions.schema.json",
46
+ "tags": [
47
+ "fn"
48
+ ]
49
+ },
50
+ {
51
+ "name": "status_from_error",
52
+ "schema": "packages/ree_roda/schemas/ree_roda/services/status_from_error.schema.json",
53
+ "tags": [
54
+ "fn"
55
+ ]
56
+ }
57
+ ]
58
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "ree"
4
+
5
+ Ree.init(__dir__, irb: true)
@@ -0,0 +1,46 @@
1
+ package_require("ree_errors/error")
2
+ package_require("ree_mapper/errors/type_error")
3
+
4
+ class ReeRoda::App < Roda
5
+ include Ree::LinkDSL
6
+
7
+ link :logger, from: :ree_logger
8
+ link :status_from_error
9
+ link :to_json, from: :ree_json
10
+
11
+ plugin :error_handler
12
+ plugin :json_parser
13
+ plugin :type_routing, default_type: :json
14
+
15
+ error do |e|
16
+ response["Content-Type"] = "application/json"
17
+
18
+ if e.is_a?(ReeErrors::Error)
19
+ body = {
20
+ code: e.code,
21
+ message: e.message,
22
+ type: e.type,
23
+ }
24
+
25
+ response.status = status_from_error(e.type)
26
+ response.write(to_json(body))
27
+ response.finish
28
+ elsif e.is_a?(ReeMapper::TypeError) || e.is_a?(ReeMapper::CoercionError)
29
+ body = {
30
+ code: "param",
31
+ message: e.message,
32
+ type: :invalid_param,
33
+ }
34
+
35
+ response.status = 400
36
+ response.write(to_json(body))
37
+ response.finish
38
+ else
39
+ logger.error(e.message, {}, e)
40
+ response["Content-Type"] = "text/plain"
41
+ response.status = 500
42
+ response.write("unhandled server error")
43
+ response.finish
44
+ end
45
+ end
46
+ end