easy_talk 3.1.0 → 3.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.yardopts +13 -0
  4. data/CHANGELOG.md +75 -0
  5. data/README.md +616 -35
  6. data/Rakefile +27 -0
  7. data/docs/.gitignore +1 -0
  8. data/docs/about.markdown +28 -8
  9. data/docs/getting-started.markdown +102 -0
  10. data/docs/index.markdown +51 -4
  11. data/docs/json_schema_compliance.md +55 -0
  12. data/docs/nested-models.markdown +216 -0
  13. data/docs/property-types.markdown +212 -0
  14. data/docs/schema-definition.markdown +180 -0
  15. data/lib/easy_talk/builders/base_builder.rb +4 -2
  16. data/lib/easy_talk/builders/composition_builder.rb +10 -12
  17. data/lib/easy_talk/builders/object_builder.rb +45 -30
  18. data/lib/easy_talk/builders/registry.rb +168 -0
  19. data/lib/easy_talk/builders/typed_array_builder.rb +15 -4
  20. data/lib/easy_talk/configuration.rb +31 -1
  21. data/lib/easy_talk/error_formatter/base.rb +100 -0
  22. data/lib/easy_talk/error_formatter/error_code_mapper.rb +82 -0
  23. data/lib/easy_talk/error_formatter/flat.rb +38 -0
  24. data/lib/easy_talk/error_formatter/json_pointer.rb +38 -0
  25. data/lib/easy_talk/error_formatter/jsonapi.rb +64 -0
  26. data/lib/easy_talk/error_formatter/path_converter.rb +53 -0
  27. data/lib/easy_talk/error_formatter/rfc7807.rb +69 -0
  28. data/lib/easy_talk/error_formatter.rb +143 -0
  29. data/lib/easy_talk/errors.rb +2 -0
  30. data/lib/easy_talk/errors_helper.rb +63 -34
  31. data/lib/easy_talk/model.rb +123 -90
  32. data/lib/easy_talk/model_helper.rb +13 -0
  33. data/lib/easy_talk/naming_strategies.rb +20 -0
  34. data/lib/easy_talk/property.rb +16 -94
  35. data/lib/easy_talk/ref_helper.rb +27 -0
  36. data/lib/easy_talk/schema.rb +198 -0
  37. data/lib/easy_talk/schema_definition.rb +7 -1
  38. data/lib/easy_talk/schema_methods.rb +80 -0
  39. data/lib/easy_talk/tools/function_builder.rb +1 -1
  40. data/lib/easy_talk/type_introspection.rb +178 -0
  41. data/lib/easy_talk/types/base_composer.rb +2 -1
  42. data/lib/easy_talk/types/composer.rb +4 -0
  43. data/lib/easy_talk/validation_adapters/active_model_adapter.rb +329 -0
  44. data/lib/easy_talk/validation_adapters/base.rb +144 -0
  45. data/lib/easy_talk/validation_adapters/none_adapter.rb +36 -0
  46. data/lib/easy_talk/validation_adapters/registry.rb +87 -0
  47. data/lib/easy_talk/validation_builder.rb +28 -309
  48. data/lib/easy_talk/version.rb +1 -1
  49. data/lib/easy_talk.rb +41 -0
  50. metadata +26 -4
  51. data/docs/404.html +0 -25
  52. data/docs/_posts/2024-05-07-welcome-to-jekyll.markdown +0 -29
  53. data/easy_talk.gemspec +0 -39
@@ -1,327 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'uri'
4
-
5
3
  module EasyTalk
6
- # The ValidationBuilder creates ActiveModel validations based on JSON Schema constraints
4
+ # @deprecated Use EasyTalk::ValidationAdapters::ActiveModelAdapter instead.
5
+ #
6
+ # The ValidationBuilder class is kept for backward compatibility.
7
+ # It delegates to the ActiveModelAdapter and shows a deprecation warning.
8
+ #
9
+ # This class will be removed in a future major version.
10
+ #
11
+ # @example Migration
12
+ # # Before (deprecated)
13
+ # EasyTalk::ValidationBuilder.build_validations(klass, :name, String, {})
14
+ #
15
+ # # After (recommended)
16
+ # EasyTalk::ValidationAdapters::ActiveModelAdapter.build_validations(klass, :name, String, {})
17
+ #
7
18
  class ValidationBuilder
8
- # Build validations for a property and apply them to the model class
19
+ @deprecation_warned = false
20
+
21
+ # Build validations for a property and apply them to the model class.
9
22
  #
23
+ # @deprecated Use EasyTalk::ValidationAdapters::ActiveModelAdapter.build_validations instead.
10
24
  # @param klass [Class] The model class to apply validations to
11
25
  # @param property_name [Symbol, String] The name of the property
12
26
  # @param type [Class, Object] The type of the property
13
27
  # @param constraints [Hash] The JSON Schema constraints for the property
14
28
  # @return [void]
15
29
  def self.build_validations(klass, property_name, type, constraints)
16
- builder = new(klass, property_name, type, constraints)
17
- builder.apply_validations
18
- end
19
-
20
- # Initialize a new ValidationBuilder
21
- #
22
- # @param klass [Class] The model class to apply validations to
23
- # @param property_name [Symbol, String] The name of the property
24
- # @param type [Class, Object] The type of the property
25
- # @param constraints [Hash] The JSON Schema constraints for the property
26
- attr_reader :klass, :property_name, :type, :constraints
27
-
28
- def initialize(klass, property_name, type, constraints)
29
- @klass = klass
30
- @property_name = property_name.to_sym
31
- @type = type
32
- @constraints = constraints || {}
33
- end
34
-
35
- # Apply validations based on property type and constraints
36
- def apply_validations
37
- # Determine if the type is boolean
38
- type_class = get_type_class(@type)
39
- is_boolean = type_class == [TrueClass, FalseClass] ||
40
- type_class == TrueClass ||
41
- type_class == FalseClass ||
42
- @type.to_s.include?('T::Boolean')
43
-
44
- # Skip presence validation for booleans and nilable types
45
- apply_presence_validation unless optional? || is_boolean || nilable_type?
46
- if nilable_type?
47
- # For nilable types, get the inner type and apply validations to it
48
- inner_type = extract_inner_type(@type)
49
- apply_type_validations(inner_type)
50
- else
51
- apply_type_validations(@type)
52
- end
53
-
54
- # Common validations for most types
55
- apply_enum_validation if @constraints[:enum]
56
- apply_const_validation if @constraints[:const]
57
- end
58
-
59
- private
60
-
61
- # Determine if a property is optional based on constraints and configuration
62
- def optional?
63
- @constraints[:optional] == true ||
64
- (@type.respond_to?(:nilable?) && @type.nilable? && EasyTalk.configuration.nilable_is_optional)
65
- end
66
-
67
- # Check if the type is nilable (e.g., T.nilable(String))
68
- def nilable_type?(type = @type)
69
- type.respond_to?(:nilable?) && type.nilable?
70
- end
71
-
72
- # Extract the inner type from a complex type like T.nilable(String)
73
- def extract_inner_type(type)
74
- if type.respond_to?(:unwrap_nilable) && type.unwrap_nilable.respond_to?(:raw_type)
75
- type.unwrap_nilable.raw_type
76
- elsif type.respond_to?(:types)
77
- # For union types like T.nilable(String), extract the non-nil type
78
- type.types.find { |t| t.respond_to?(:raw_type) && t.raw_type != NilClass }
79
- else
80
- type
81
- end
82
- end
83
-
84
- # Apply validations based on the type of the property
85
- def apply_type_validations(type)
86
- type_class = get_type_class(type)
87
-
88
- if type_class == String
89
- apply_string_validations
90
- elsif type_class == Integer
91
- apply_integer_validations
92
- elsif [Float, BigDecimal].include?(type_class)
93
- apply_number_validations
94
- elsif type_class == Array
95
- apply_array_validations(type)
96
- elsif type_class == [TrueClass,
97
- FalseClass] || [TrueClass,
98
- FalseClass].include?(type_class) || type.to_s.include?('T::Boolean')
99
- apply_boolean_validations
100
- elsif type_class.is_a?(Object) && type_class.include?(EasyTalk::Model)
101
- apply_object_validations
102
- end
103
- end
104
-
105
- # Determine the actual class for a type, handling Sorbet types
106
- def get_type_class(type)
107
- if type.is_a?(Class)
108
- type
109
- elsif type.respond_to?(:raw_type)
110
- type.raw_type
111
- elsif type.is_a?(T::Types::TypedArray)
112
- Array
113
- elsif type.is_a?(Symbol) || type.is_a?(String)
114
- begin
115
- type.to_s.classify.constantize
116
- rescue StandardError
117
- String
118
- end
119
- elsif type.to_s.include?('T::Boolean')
120
- [TrueClass, FalseClass] # Return both boolean classes
121
- elsif nilable_type?(type)
122
- extract_inner_type(type)
123
- else
124
- String # Default fallback
125
- end
126
- end
127
-
128
- # Add presence validation for the property
129
- def apply_presence_validation
130
- @klass.validates @property_name, presence: true
131
- end
132
-
133
- # Validate string-specific constraints
134
- def apply_string_validations
135
- # Handle format constraints
136
- apply_format_validation(@constraints[:format]) if @constraints[:format]
137
-
138
- # Handle pattern (regex) constraints
139
- @klass.validates @property_name, format: { with: Regexp.new(@constraints[:pattern]) } if @constraints[:pattern]
140
-
141
- # Handle length constraints
142
- begin
143
- length_options = {}
144
- length_options[:minimum] = @constraints[:min_length] if @constraints[:min_length].is_a?(Numeric) && @constraints[:min_length] >= 0
145
- length_options[:maximum] = @constraints[:max_length] if @constraints[:max_length].is_a?(Numeric) && @constraints[:max_length] >= 0
146
- @klass.validates @property_name, length: length_options if length_options.any?
147
- rescue ArgumentError
148
- # Silently ignore invalid length constraints
149
- end
150
- end
151
-
152
- # Apply format-specific validations (email, url, etc.)
153
- def apply_format_validation(format)
154
- format_configs = {
155
- 'email' => { with: URI::MailTo::EMAIL_REGEXP, message: 'must be a valid email address' },
156
- 'uri' => { with: URI::DEFAULT_PARSER.make_regexp, message: 'must be a valid URL' },
157
- 'url' => { with: URI::DEFAULT_PARSER.make_regexp, message: 'must be a valid URL' },
158
- 'uuid' => { with: /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i, message: 'must be a valid UUID' },
159
- 'date' => { with: /\A\d{4}-\d{2}-\d{2}\z/, message: 'must be a valid date in YYYY-MM-DD format' },
160
- 'date-time' => { with: /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?\z/, message: 'must be a valid ISO 8601 date-time' },
161
- 'time' => { with: /\A\d{2}:\d{2}:\d{2}(?:\.\d+)?\z/, message: 'must be a valid time in HH:MM:SS format' }
162
- }
163
-
164
- config = format_configs[format.to_s]
165
- @klass.validates @property_name, format: config if config
166
- end
167
-
168
- # Validate integer-specific constraints
169
- def apply_integer_validations
170
- apply_numeric_validations(only_integer: true)
171
- end
172
-
173
- # Validate number-specific constraints
174
- def apply_number_validations
175
- apply_numeric_validations(only_integer: false)
176
- end
177
-
178
- # Apply numeric validations for integers and floats
179
- def apply_numeric_validations(only_integer: false)
180
- begin
181
- options = { only_integer: only_integer }
182
-
183
- # Add range constraints - only if they are numeric
184
- options[:greater_than_or_equal_to] = @constraints[:minimum] if @constraints[:minimum].is_a?(Numeric)
185
- options[:less_than_or_equal_to] = @constraints[:maximum] if @constraints[:maximum].is_a?(Numeric)
186
- options[:greater_than] = @constraints[:exclusive_minimum] if @constraints[:exclusive_minimum].is_a?(Numeric)
187
- options[:less_than] = @constraints[:exclusive_maximum] if @constraints[:exclusive_maximum].is_a?(Numeric)
188
-
189
- @klass.validates @property_name, numericality: options
190
- rescue ArgumentError
191
- # Silently ignore invalid numeric constraints
30
+ unless @deprecation_warned
31
+ warn "[DEPRECATION] EasyTalk::ValidationBuilder is deprecated and will be removed in a future version. " \
32
+ "Use EasyTalk::ValidationAdapters::ActiveModelAdapter instead."
33
+ @deprecation_warned = true
192
34
  end
193
35
 
194
- # Add multiple_of validation
195
- return unless @constraints[:multiple_of]
196
-
197
- prop_name = @property_name
198
- multiple_of_value = @constraints[:multiple_of]
199
- @klass.validate do |record|
200
- value = record.public_send(prop_name)
201
- record.errors.add(prop_name, "must be a multiple of #{multiple_of_value}") if value && (value % multiple_of_value != 0)
202
- end
36
+ ValidationAdapters::ActiveModelAdapter.build_validations(klass, property_name, type, constraints)
203
37
  end
204
38
 
205
- # Validate array-specific constraints
206
- def apply_array_validations(type)
207
- # Validate array length
208
- if @constraints[:min_items] || @constraints[:max_items]
209
- length_options = {}
210
- length_options[:minimum] = @constraints[:min_items] if @constraints[:min_items]
211
- length_options[:maximum] = @constraints[:max_items] if @constraints[:max_items]
212
-
213
- @klass.validates @property_name, length: length_options
214
- end
215
-
216
- # Validate uniqueness within the array
217
- if @constraints[:unique_items]
218
- prop_name = @property_name
219
- @klass.validate do |record|
220
- value = record.public_send(prop_name)
221
- record.errors.add(prop_name, 'must contain unique items') if value && value.uniq.length != value.length
222
- end
223
- end
224
-
225
- # Validate array item types if using T::Array[SomeType]
226
- return unless type.respond_to?(:type_parameter)
227
-
228
- inner_type = type.type_parameter
229
- prop_name = @property_name
230
- @klass.validate do |record|
231
- value = record.public_send(prop_name)
232
- if value.is_a?(Array)
233
- value.each_with_index do |item, index|
234
- record.errors.add(prop_name, "item at index #{index} must be a #{inner_type}") unless item.is_a?(inner_type)
235
- end
236
- end
237
- end
238
- end
239
-
240
- # Validate boolean-specific constraints
241
- def apply_boolean_validations
242
- # For boolean values, validate inclusion in [true, false]
243
- # If not optional, don't allow nil (equivalent to presence validation for booleans)
244
- if optional?
245
- @klass.validates @property_name, inclusion: { in: [true, false] }, allow_nil: true
246
- else
247
- @klass.validates @property_name, inclusion: { in: [true, false] }
248
- # Add custom validation for nil values that provides the "can't be blank" message
249
- prop_name = @property_name
250
- @klass.validate do |record|
251
- value = record.public_send(prop_name)
252
- record.errors.add(prop_name, "can't be blank") if value.nil?
253
- end
254
- end
255
-
256
- # Add type validation to ensure the value is actually a boolean
257
- prop_name = @property_name
258
- @klass.validate do |record|
259
- value = record.public_send(prop_name)
260
- record.errors.add(prop_name, 'must be a boolean') if value && ![true, false].include?(value)
261
- end
262
- end
263
-
264
- # Validate object/hash-specific constraints
265
- def apply_object_validations
266
- # Capture necessary variables outside the validation block's scope
267
- prop_name = @property_name
268
- expected_type = get_type_class(@type) # Get the raw model class
269
-
270
- @klass.validate do |record|
271
- nested_object = record.public_send(prop_name)
272
-
273
- # Only validate if the nested object is present
274
- if nested_object
275
- # Check if the object is of the expected type (e.g., an actual Email instance)
276
- if nested_object.is_a?(expected_type)
277
- # Check if this object appears to be empty (created from an empty hash)
278
- # by checking if all defined properties are nil/blank
279
- properties = expected_type.schema_definition.schema[:properties] || {}
280
- all_properties_blank = properties.keys.all? do |property|
281
- value = nested_object.public_send(property)
282
- value.nil? || (value.respond_to?(:empty?) && value.empty?)
283
- end
284
-
285
- if all_properties_blank
286
- # Treat as blank and add a presence error to the parent field
287
- record.errors.add(prop_name, "can't be blank")
288
- else
289
- # If it's the correct type and not empty, validate it
290
- unless nested_object.valid?
291
- # Merge errors from the nested object into the parent
292
- nested_object.errors.each do |error|
293
- # Prefix the attribute name (e.g., 'email.address')
294
- nested_key = "#{prop_name}.#{error.attribute}"
295
- record.errors.add(nested_key.to_sym, error.message)
296
- end
297
- end
298
- end
299
- else
300
- # If present but not the correct type, add a type error
301
- record.errors.add(prop_name, "must be a valid #{expected_type.name}")
302
- end
303
- end
304
- # NOTE: Presence validation (if nested_object is nil) is handled
305
- # by apply_presence_validation based on the property definition.
306
- end
307
- end
308
-
309
- # Apply enum validation for inclusion in a specific list
310
- def apply_enum_validation
311
- @klass.validates @property_name, inclusion: {
312
- in: @constraints[:enum],
313
- message: "must be one of: #{@constraints[:enum].join(', ')}"
314
- }
315
- end
316
-
317
- # Apply const validation for equality with a specific value
318
- def apply_const_validation
319
- const_value = @constraints[:const]
320
- prop_name = @property_name
321
- @klass.validate do |record|
322
- value = record.public_send(prop_name)
323
- record.errors.add(prop_name, "must be equal to #{const_value}") if !value.nil? && value != const_value
324
- end
39
+ # Reset the deprecation warning flag (useful for testing).
40
+ #
41
+ # @api private
42
+ def self.reset_deprecation_warning!
43
+ @deprecation_warned = false
325
44
  end
326
45
  end
327
46
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EasyTalk
4
- VERSION = '3.1.0'
4
+ VERSION = '3.2.0'
5
5
  end
data/lib/easy_talk.rb CHANGED
@@ -5,15 +5,56 @@ module EasyTalk
5
5
  require 'sorbet-runtime'
6
6
  require 'easy_talk/sorbet_extension'
7
7
  require 'easy_talk/errors'
8
+ require 'easy_talk/type_introspection'
8
9
  require 'easy_talk/errors_helper'
9
10
  require 'easy_talk/configuration'
11
+ require 'easy_talk/schema_methods'
10
12
  require 'easy_talk/types/composer'
13
+
14
+ # Validation adapters
15
+ require 'easy_talk/validation_adapters/base'
16
+ require 'easy_talk/validation_adapters/registry'
17
+ require 'easy_talk/validation_adapters/active_model_adapter'
18
+ require 'easy_talk/validation_adapters/none_adapter'
19
+
20
+ # Builder registry for pluggable type support
21
+ require 'easy_talk/builders/registry'
22
+
11
23
  require 'easy_talk/model'
24
+ require 'easy_talk/schema'
12
25
  require 'easy_talk/property'
13
26
  require 'easy_talk/schema_definition'
27
+ require 'easy_talk/validation_builder'
28
+ require 'easy_talk/error_formatter'
14
29
  require 'easy_talk/tools/function_builder'
15
30
  require 'easy_talk/version'
16
31
 
32
+ # Register default validation adapters
33
+ ValidationAdapters::Registry.register_default_adapters
34
+
35
+ # Register built-in type builders
36
+ Builders::Registry.register_built_in_types
37
+
38
+ # Register a custom type with its corresponding schema builder.
39
+ #
40
+ # This allows extending EasyTalk with domain-specific types without
41
+ # modifying the gem's source code.
42
+ #
43
+ # @param type_key [Class, String, Symbol] The type to register
44
+ # @param builder_class [Class] The builder class that generates JSON Schema
45
+ # @param collection [Boolean] Whether this is a collection type builder
46
+ # Collection builders receive (name, type, constraints) instead of (name, constraints)
47
+ # @return [void]
48
+ #
49
+ # @example Register a custom Money type
50
+ # EasyTalk.register_type(Money, MoneySchemaBuilder)
51
+ #
52
+ # @example Register a collection type
53
+ # EasyTalk.register_type(CustomArray, CustomArrayBuilder, collection: true)
54
+ def self.register_type(type_key, builder_class, collection: false)
55
+ Builders::Registry.register(type_key, builder_class, collection: collection)
56
+ end
57
+
17
58
  def self.assert_valid_property_options(property_name, options, *valid_keys)
18
59
  valid_keys.flatten!
19
60
  options.each_key do |k|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_talk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio Bayona
@@ -86,19 +86,22 @@ extensions: []
86
86
  extra_rdoc_files: []
87
87
  files:
88
88
  - ".rubocop.yml"
89
+ - ".yardopts"
89
90
  - CHANGELOG.md
90
91
  - CONSTRAINTS.md
91
92
  - LICENSE.txt
92
93
  - README.md
93
94
  - Rakefile
94
95
  - docs/.gitignore
95
- - docs/404.html
96
96
  - docs/Gemfile
97
97
  - docs/_config.yml
98
- - docs/_posts/2024-05-07-welcome-to-jekyll.markdown
99
98
  - docs/about.markdown
99
+ - docs/getting-started.markdown
100
100
  - docs/index.markdown
101
- - easy_talk.gemspec
101
+ - docs/json_schema_compliance.md
102
+ - docs/nested-models.markdown
103
+ - docs/property-types.markdown
104
+ - docs/schema-definition.markdown
102
105
  - lib/easy_talk.rb
103
106
  - lib/easy_talk/builders/base_builder.rb
104
107
  - lib/easy_talk/builders/boolean_builder.rb
@@ -108,21 +111,40 @@ files:
108
111
  - lib/easy_talk/builders/null_builder.rb
109
112
  - lib/easy_talk/builders/number_builder.rb
110
113
  - lib/easy_talk/builders/object_builder.rb
114
+ - lib/easy_talk/builders/registry.rb
111
115
  - lib/easy_talk/builders/string_builder.rb
112
116
  - lib/easy_talk/builders/temporal_builder.rb
113
117
  - lib/easy_talk/builders/typed_array_builder.rb
114
118
  - lib/easy_talk/builders/union_builder.rb
115
119
  - lib/easy_talk/configuration.rb
120
+ - lib/easy_talk/error_formatter.rb
121
+ - lib/easy_talk/error_formatter/base.rb
122
+ - lib/easy_talk/error_formatter/error_code_mapper.rb
123
+ - lib/easy_talk/error_formatter/flat.rb
124
+ - lib/easy_talk/error_formatter/json_pointer.rb
125
+ - lib/easy_talk/error_formatter/jsonapi.rb
126
+ - lib/easy_talk/error_formatter/path_converter.rb
127
+ - lib/easy_talk/error_formatter/rfc7807.rb
116
128
  - lib/easy_talk/errors.rb
117
129
  - lib/easy_talk/errors_helper.rb
118
130
  - lib/easy_talk/keywords.rb
119
131
  - lib/easy_talk/model.rb
132
+ - lib/easy_talk/model_helper.rb
133
+ - lib/easy_talk/naming_strategies.rb
120
134
  - lib/easy_talk/property.rb
135
+ - lib/easy_talk/ref_helper.rb
136
+ - lib/easy_talk/schema.rb
121
137
  - lib/easy_talk/schema_definition.rb
138
+ - lib/easy_talk/schema_methods.rb
122
139
  - lib/easy_talk/sorbet_extension.rb
123
140
  - lib/easy_talk/tools/function_builder.rb
141
+ - lib/easy_talk/type_introspection.rb
124
142
  - lib/easy_talk/types/base_composer.rb
125
143
  - lib/easy_talk/types/composer.rb
144
+ - lib/easy_talk/validation_adapters/active_model_adapter.rb
145
+ - lib/easy_talk/validation_adapters/base.rb
146
+ - lib/easy_talk/validation_adapters/none_adapter.rb
147
+ - lib/easy_talk/validation_adapters/registry.rb
126
148
  - lib/easy_talk/validation_builder.rb
127
149
  - lib/easy_talk/version.rb
128
150
  homepage: https://github.com/sergiobayona/easy_talk
data/docs/404.html DELETED
@@ -1,25 +0,0 @@
1
- ---
2
- permalink: /404.html
3
- layout: default
4
- ---
5
-
6
- <style type="text/css" media="screen">
7
- .container {
8
- margin: 10px auto;
9
- max-width: 600px;
10
- text-align: center;
11
- }
12
- h1 {
13
- margin: 30px 0;
14
- font-size: 4em;
15
- line-height: 1;
16
- letter-spacing: -1px;
17
- }
18
- </style>
19
-
20
- <div class="container">
21
- <h1>404</h1>
22
-
23
- <p><strong>Page not found :(</strong></p>
24
- <p>The requested page could not be found.</p>
25
- </div>
@@ -1,29 +0,0 @@
1
- ---
2
- layout: post
3
- title: "Welcome to Jekyll!"
4
- date: 2024-05-07 18:39:19 -0500
5
- categories: jekyll update
6
- ---
7
- You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
8
-
9
- Jekyll requires blog post files to be named according to the following format:
10
-
11
- `YEAR-MONTH-DAY-title.MARKUP`
12
-
13
- Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
14
-
15
- Jekyll also offers powerful support for code snippets:
16
-
17
- {% highlight ruby %}
18
- def print_hi(name)
19
- puts "Hi, #{name}"
20
- end
21
- print_hi('Tom')
22
- #=> prints 'Hi, Tom' to STDOUT.
23
- {% endhighlight %}
24
-
25
- Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
26
-
27
- [jekyll-docs]: https://jekyllrb.com/docs/home
28
- [jekyll-gh]: https://github.com/jekyll/jekyll
29
- [jekyll-talk]: https://talk.jekyllrb.com/
data/easy_talk.gemspec DELETED
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'lib/easy_talk/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'easy_talk'
7
- spec.version = EasyTalk::VERSION
8
- spec.authors = ['Sergio Bayona']
9
- spec.email = ['bayona.sergio@gmail.com']
10
-
11
- spec.summary = 'Generate json-schema from Ruby classes with ActiveModel integration.'
12
- spec.description = 'Generate json-schema from plain Ruby classes with ActiveModel integration for validations and serialization.'
13
- spec.homepage = 'https://github.com/sergiobayona/easy_talk'
14
- spec.license = 'MIT'
15
- spec.required_ruby_version = '>= 3.2'
16
-
17
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
-
19
- spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['changelog_uri'] = 'https://github.com/sergiobayona/easy_talk/blob/main/CHANGELOG.md'
21
-
22
- # Specify which files should be added to the gem when it is released.
23
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
- spec.files = Dir.chdir(__dir__) do
25
- `git ls-files -z`.split("\x0").reject do |f|
26
- (File.expand_path(f) == __FILE__) ||
27
- f.start_with?(*%w[bin/ spec/ .git .github Gemfile])
28
- end
29
- end
30
-
31
- spec.require_paths = ['lib']
32
-
33
- spec.add_dependency 'activemodel', ['>= 7.0', '< 9.0']
34
- spec.add_dependency 'activesupport', ['>= 7.0', '< 9.0']
35
- spec.add_dependency 'js_regex', '~> 3.0'
36
- spec.add_dependency 'sorbet-runtime', '~> 0.5'
37
-
38
- spec.metadata['rubygems_mfa_required'] = 'true'
39
- end