rhino_project_core 0.21.0.beta.9 → 0.21.0.beta.12
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d956b01e70ce6ab2cd9541f6199bef97adeb0641829ad9f9794736f7685d823b
|
4
|
+
data.tar.gz: 672d03cbebda971049761f3cea1edecd0ca622fe321399490ec59554a120a2ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59b847bd102beae256eb2a9325f4c31d371ba0e9d61c086889824c62a7b55db2c61ee7020c8360ea2987281c2ffcf3c9d9dcb2cec87b4a97d6ca5383c4059abf
|
7
|
+
data.tar.gz: b7acc68436e1de4b91955edcb07b052f0c420f918cdf4023576c85cbc44b53e3ceb14ea4c51265845bd693bb5ff505c95077e4750f1dc3c05300627b8ffbac44
|
@@ -33,194 +33,200 @@ module Rhino
|
|
33
33
|
end
|
34
34
|
|
35
35
|
private
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def ref_descriptor(names)
|
44
|
-
{
|
45
|
-
type: :reference,
|
46
|
-
anyOf: names.map { |name| { :$ref => "#/components/schemas/#{name.singularize}" } }
|
47
|
-
}
|
48
|
-
end
|
49
|
-
|
50
|
-
def property_type_and_format_attr(name) # rubocop:todo Metrics/MethodLength
|
51
|
-
atype = attribute_types[name.to_s].type
|
52
|
-
|
53
|
-
# The PG array delegates type to "subtype" which is the actual type of the array elements
|
54
|
-
if attribute_types[name.to_s].is_a? ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array
|
55
|
-
return {
|
56
|
-
type: :array,
|
57
|
-
items: {
|
58
|
-
type: atype
|
59
|
-
}
|
60
|
-
}
|
36
|
+
# FIXME: It can be a hash if passed in from a reference which might have something like
|
37
|
+
# rhino_references %i[{blog_posts: [:comments]}]
|
38
|
+
# but I cannot find current spot where it is used like that currently
|
39
|
+
def property_name(property)
|
40
|
+
property.is_a?(Hash) ? property.keys.first : property
|
61
41
|
end
|
62
42
|
|
63
|
-
|
64
|
-
|
65
|
-
type:
|
66
|
-
|
43
|
+
def ref_descriptor(names)
|
44
|
+
{
|
45
|
+
type: :reference,
|
46
|
+
anyOf: names.map { |name| { :$ref => "#/components/schemas/#{name.singularize}" } }
|
67
47
|
}
|
68
48
|
end
|
69
49
|
|
70
|
-
|
71
|
-
|
50
|
+
def property_type_and_format_attr(name) # rubocop:todo Metrics/MethodLength
|
51
|
+
atype = attribute_types[name.to_s].type
|
72
52
|
|
73
|
-
|
74
|
-
|
53
|
+
# The PG array delegates type to "subtype" which is the actual type of the array elements
|
54
|
+
if attribute_types[name.to_s].is_a? ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array
|
55
|
+
return {
|
56
|
+
type: :array,
|
57
|
+
items: {
|
58
|
+
type: atype
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
75
62
|
|
76
|
-
|
63
|
+
if %i[datetime date time].include?(atype)
|
64
|
+
return {
|
65
|
+
type: "string",
|
66
|
+
format: atype
|
67
|
+
}
|
68
|
+
end
|
77
69
|
|
78
|
-
|
79
|
-
array_options[:creatable] = true
|
80
|
-
array_options[:updatable] = true
|
81
|
-
array_options[:destroyable] = nested_attributes_options[ref_sym][:allow_destroy]
|
70
|
+
{ type: atype }
|
82
71
|
end
|
83
72
|
|
84
|
-
|
85
|
-
|
73
|
+
def nested_array_options(name)
|
74
|
+
ref_sym = name.to_sym
|
86
75
|
|
87
|
-
|
88
|
-
# rubocop:todo Metrics/AbcSize
|
89
|
-
def property_type_and_format_ref(name) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
90
|
-
assoc = reflections[name]
|
91
|
-
klasses = if assoc.options[:polymorphic]
|
92
|
-
assoc.active_record.send("#{assoc.name}_types").map(&:constantize).map { |m| m.model_name.singular }
|
93
|
-
else
|
94
|
-
# FIXME: The tr hack is to match how model_name in rails handles modularized classes
|
95
|
-
[assoc.options[:class_name]&.underscore&.tr('/', '_') || name]
|
96
|
-
end
|
76
|
+
array_options = {}
|
97
77
|
|
98
|
-
|
78
|
+
if nested_attributes_options[ref_sym]
|
79
|
+
array_options[:creatable] = true
|
80
|
+
array_options[:updatable] = true
|
81
|
+
array_options[:destroyable] = nested_attributes_options[ref_sym][:allow_destroy]
|
82
|
+
end
|
99
83
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
84
|
+
{ "x-rhino-attribute-array": array_options.merge(_properties_array[ref_sym] || {}) }
|
85
|
+
end
|
86
|
+
|
87
|
+
# rubocop:todo Metrics/PerceivedComplexity
|
88
|
+
# rubocop:todo Metrics/AbcSize
|
89
|
+
def property_type_and_format_ref(name) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
90
|
+
assoc = reflections[name]
|
91
|
+
klasses = if assoc.options[:polymorphic]
|
92
|
+
# If its a delgated type it will have type introspection
|
93
|
+
if assoc.active_record.respond_to?("#{assoc.name}_types")
|
94
|
+
assoc.active_record.send("#{assoc.name}_types").map(&:constantize).map { |m| m.model_name.singular }
|
95
|
+
else
|
96
|
+
# FIXME: This is wrong, but there is no good way to introspect general polymorphic models
|
97
|
+
[name]
|
98
|
+
end
|
99
|
+
else
|
100
|
+
# FIXME: The tr hack is to match how model_name in rails handles modularized classes
|
101
|
+
[assoc.options[:class_name]&.underscore&.tr("/", "_") || name]
|
102
|
+
end
|
107
103
|
|
108
|
-
|
109
|
-
# Special cases
|
110
|
-
return { type: :identifier } if name == identifier_property
|
111
|
-
return { type: :string } if defined_enums.key?(name)
|
104
|
+
return ref_descriptor(klasses) unless reflections[name].macro == :has_many
|
112
105
|
|
113
|
-
|
114
|
-
if attribute_types.key?(name.to_s) && attribute_types[name.to_s].class.to_s == 'ActsAsTaggableOn::Taggable::TagListType'
|
115
|
-
return {
|
106
|
+
{
|
116
107
|
type: :array,
|
117
|
-
items:
|
118
|
-
type: 'string'
|
119
|
-
}
|
108
|
+
items: ref_descriptor(klasses).merge(nested_array_options(name))
|
120
109
|
}
|
121
110
|
end
|
111
|
+
# rubocop:enable Metrics/AbcSize
|
112
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
113
|
+
|
114
|
+
def property_type_and_format(name) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
115
|
+
# Special cases
|
116
|
+
return { type: :identifier } if name == identifier_property
|
117
|
+
return { type: :string } if defined_enums.key?(name)
|
118
|
+
|
119
|
+
# FIXME: Hack for tags for now
|
120
|
+
if attribute_types.key?(name.to_s) && attribute_types[name.to_s].class.to_s == "ActsAsTaggableOn::Taggable::TagListType"
|
121
|
+
return {
|
122
|
+
type: :array,
|
123
|
+
items: {
|
124
|
+
type: "string"
|
125
|
+
}
|
126
|
+
}
|
127
|
+
end
|
122
128
|
|
123
|
-
|
124
|
-
|
129
|
+
# Use the attribute type if possible
|
130
|
+
return property_type_and_format_attr(name) if attribute_types.key?(name.to_s)
|
125
131
|
|
126
|
-
|
132
|
+
return property_type_and_format_ref(name) if reflections.key?(name)
|
127
133
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
134
|
+
# FIXME: There may be no way to reach this
|
135
|
+
# raise UnknownpropertyType
|
136
|
+
{ type: :unknown }
|
137
|
+
end
|
132
138
|
|
133
|
-
|
134
|
-
|
139
|
+
def property_overrides(property)
|
140
|
+
return {} unless _properties_overrides.key?(property)
|
135
141
|
|
136
|
-
|
137
|
-
|
142
|
+
_properties_overrides[property].deep_symbolize_keys
|
143
|
+
end
|
138
144
|
|
139
|
-
|
140
|
-
|
145
|
+
def property_validations(property) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
146
|
+
constraint_hash = {}
|
141
147
|
|
142
|
-
|
148
|
+
# https://swagger.io/specification/
|
143
149
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
validators_on(property).each do |v|
|
151
|
+
if v.is_a? ActiveModel::Validations::NumericalityValidator
|
152
|
+
if v.options.key?(:greater_than)
|
153
|
+
constraint_hash[:minimum] = v.options[:greater_than]
|
154
|
+
constraint_hash[:exclusiveMinimum] = true
|
155
|
+
end
|
150
156
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
157
|
+
if v.options.key?(:less_than)
|
158
|
+
constraint_hash[:maximum] = v.options[:less_than]
|
159
|
+
constraint_hash[:exclusiveMaximum] = true
|
160
|
+
end
|
155
161
|
|
156
|
-
|
157
|
-
|
162
|
+
constraint_hash[:minimum] = v.options[:greater_than_or_equal_to] if v.options.key?(:greater_than_or_equal_to)
|
163
|
+
constraint_hash[:maximum] = v.options[:less_than_or_equal_to] if v.options.key?(:less_than_or_equal_to)
|
158
164
|
|
159
|
-
|
160
|
-
|
161
|
-
|
165
|
+
if v.options.key?(:in)
|
166
|
+
constraint_hash[:minimum] = v.options[:in].min
|
167
|
+
constraint_hash[:maximum] = v.options[:in].max
|
168
|
+
end
|
162
169
|
end
|
163
|
-
end
|
164
|
-
|
165
|
-
if v.is_a? ::ActiveRecord::Validations::LengthValidator
|
166
|
-
constraint_hash[:minLength] = v.options[:minimum] || v.options[:is]
|
167
|
-
constraint_hash[:maxLength] = v.options[:maximum] || v.options[:is]
|
168
|
-
end
|
169
170
|
|
170
|
-
|
171
|
+
if v.is_a? ::ActiveRecord::Validations::LengthValidator
|
172
|
+
constraint_hash[:minLength] = v.options[:minimum] || v.options[:is]
|
173
|
+
constraint_hash[:maxLength] = v.options[:maximum] || v.options[:is]
|
174
|
+
end
|
171
175
|
|
172
|
-
|
173
|
-
end
|
176
|
+
constraint_hash[:pattern] = JsRegex.new(v.options[:with]).source if v.is_a? ::ActiveModel::Validations::FormatValidator
|
174
177
|
|
175
|
-
|
178
|
+
constraint_hash[:enum] = v.options[:in] if v.is_a? ActiveModel::Validations::InclusionValidator
|
179
|
+
end
|
176
180
|
|
177
|
-
|
178
|
-
end
|
181
|
+
constraint_hash[:enum] = defined_enums[property].keys if defined_enums.key?(property)
|
179
182
|
|
180
|
-
|
181
|
-
# if there is no optional: true on an association, rails will add a
|
182
|
-
# presence validator automatically
|
183
|
-
# Otherwise check the db for the actual column or foreign key setting
|
184
|
-
# Return nil instead of false for compaction
|
185
|
-
def property_nullable?(name) # rubocop:todo Metrics/AbcSize
|
186
|
-
# Check for any presence validator
|
187
|
-
return false if validators_on(name).any?(::ActiveRecord::Validations::PresenceValidator)
|
188
|
-
|
189
|
-
# https://guides.rubyonrails.org/active_record_validations.html#numericality
|
190
|
-
# By default, numericality doesn't allow nil values. You can use allow_nil: true option to permit it.
|
191
|
-
validators_on(name).select { |v| v.is_a? ::ActiveRecord::Validations::NumericalityValidator }.each do |v|
|
192
|
-
return false unless v.options[:allow_nil]
|
183
|
+
constraint_hash.compact
|
193
184
|
end
|
194
185
|
|
195
|
-
|
186
|
+
# If there is a presence validator in the model it is not nullable.
|
187
|
+
# if there is no optional: true on an association, rails will add a
|
188
|
+
# presence validator automatically
|
189
|
+
# Otherwise check the db for the actual column or foreign key setting
|
190
|
+
# Return nil instead of false for compaction
|
191
|
+
def property_nullable?(name) # rubocop:todo Metrics/AbcSize
|
192
|
+
# Check for any presence validator
|
193
|
+
return false if validators_on(name).any?(::ActiveRecord::Validations::PresenceValidator)
|
194
|
+
|
195
|
+
# https://guides.rubyonrails.org/active_record_validations.html#numericality
|
196
|
+
# By default, numericality doesn't allow nil values. You can use allow_nil: true option to permit it.
|
197
|
+
validators_on(name).select { |v| v.is_a? ::ActiveRecord::Validations::NumericalityValidator }.each do |v|
|
198
|
+
return false unless v.options[:allow_nil]
|
199
|
+
end
|
196
200
|
|
197
|
-
|
198
|
-
return columns_hash[name].null if columns_hash.key?(name)
|
201
|
+
name = reflections[name].foreign_key if reflections.key?(name)
|
199
202
|
|
200
|
-
|
201
|
-
|
203
|
+
# Check the column null setting
|
204
|
+
return columns_hash[name].null if columns_hash.key?(name)
|
202
205
|
|
203
|
-
|
204
|
-
|
205
|
-
return unless read_properties.include?(name) && (create_properties.exclude?(name) && update_properties.exclude?(name))
|
206
|
+
true
|
207
|
+
end
|
206
208
|
|
207
|
-
|
208
|
-
|
209
|
+
# Return nil instead of false for compaction
|
210
|
+
def property_read_only?(name)
|
211
|
+
return unless read_properties.include?(name) && (create_properties.exclude?(name) && update_properties.exclude?(name))
|
209
212
|
|
210
|
-
|
211
|
-
|
212
|
-
return unless (create_properties.include?(name) || update_properties.include?(name)) && read_properties.exclude?(name)
|
213
|
+
true
|
214
|
+
end
|
213
215
|
|
214
|
-
|
215
|
-
|
216
|
+
# Return nil instead of false for compaction
|
217
|
+
def property_write_only?(name)
|
218
|
+
return unless (create_properties.include?(name) || update_properties.include?(name)) && read_properties.exclude?(name)
|
216
219
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
220
|
+
true
|
221
|
+
end
|
222
|
+
|
223
|
+
def property_default(name)
|
224
|
+
# FIXME: This will not handle datetime fields
|
225
|
+
# https://github.com/rails/rails/issues/27077 sets the default in the db
|
226
|
+
# but Blog.new does not set the default value like other attributes
|
227
|
+
# https://nubinary.atlassian.net/browse/NUB-298
|
228
|
+
_default_attributes[name].type_cast(_default_attributes[name].value_before_type_cast)
|
229
|
+
end
|
224
230
|
end
|
225
231
|
end
|
226
232
|
end
|
data/lib/rhino/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhino_project_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.21.0.beta.
|
4
|
+
version: 0.21.0.beta.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JP Rosevear
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|