easy_talk 1.0.3 → 1.0.4
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 +11 -0
- data/README.md +181 -0
- data/lib/easy_talk/active_record_schema_builder.rb +3 -0
- data/lib/easy_talk/builders/composition_builder.rb +12 -0
- data/lib/easy_talk/builders/object_builder.rb +5 -0
- data/lib/easy_talk/builders/temporal_builder.rb +49 -0
- data/lib/easy_talk/configuration.rb +3 -1
- data/lib/easy_talk/property.rb +8 -12
- data/lib/easy_talk/schema_definition.rb +17 -0
- data/lib/easy_talk/types/composer.rb +88 -0
- data/lib/easy_talk/version.rb +1 -1
- data/lib/easy_talk.rb +5 -3
- metadata +4 -11
- data/lib/easy_talk/builders/all_of_builder.rb +0 -11
- data/lib/easy_talk/builders/any_of_builder.rb +0 -11
- data/lib/easy_talk/builders/date_builder.rb +0 -18
- data/lib/easy_talk/builders/datetime_builder.rb +0 -18
- data/lib/easy_talk/builders/one_of_builder.rb +0 -11
- data/lib/easy_talk/builders/time_builder.rb +0 -16
- data/lib/easy_talk/types/all_of.rb +0 -32
- data/lib/easy_talk/types/any_of.rb +0 -39
- data/lib/easy_talk/types/one_of.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 365a704ac1e34ef3ae2796712c0eb13a15030bb9f6184578dc17ac9b2611c2d2
|
4
|
+
data.tar.gz: 94b6ed4d70c16a1ff74b519dfcf6833eb00573a5dc532d6ec7bb3565dc39d208
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1af20c3dffdc153ac5b251f6170280b46c5ee1d9d068cea2ab74f4a3a585110c820ea4d1b831eee3e0adda974ac0f10f33d7e424df4174b94246c722c0ed9119
|
7
|
+
data.tar.gz: aab1c378d3a1bacbeed497b5613f3e9a45d75a4a7288788ca5b6628aad19b27411895f8c414ff92734920018e87618f70af1a20ac61b6090981764c6c332fec6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## [1.0.4] - 2024-03-12
|
2
|
+
### Changed
|
3
|
+
- Combined composition builders into a single file (#47)
|
4
|
+
- Improved code organization and maintainability
|
5
|
+
- Refactored internal builder implementation
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
- Added support for nilable properties when database column is null (#45)
|
9
|
+
- Better handling of nullable database columns
|
10
|
+
- More accurate schema generation for ActiveRecord models
|
11
|
+
|
1
12
|
## [1.0.3] - 2025-03-11
|
2
13
|
### Added
|
3
14
|
- Unified schema generation for both plain Ruby classes and ActiveRecord models (#40)
|
data/README.md
CHANGED
@@ -860,6 +860,187 @@ property :status, String, enum: ["active", "inactive", "pending"]
|
|
860
860
|
6. Use explicit types instead of relying on inference
|
861
861
|
7. Test your schemas with sample data
|
862
862
|
|
863
|
+
# Nullable vs Optional Properties in EasyTalk
|
864
|
+
|
865
|
+
One of the most important distinctions when defining schemas is understanding the difference between **nullable** properties and **optional** properties. This guide explains these concepts and how to use them effectively in EasyTalk.
|
866
|
+
|
867
|
+
## Key Concepts
|
868
|
+
|
869
|
+
| Concept | Description | JSON Schema Effect | EasyTalk Syntax |
|
870
|
+
|---------|-------------|-------------------|-----------------|
|
871
|
+
| **Nullable** | Property can have a `null` value | Adds `"null"` to the type array | `T.nilable(Type)` |
|
872
|
+
| **Optional** | Property doesn't have to exist | Omits property from `"required"` array | `optional: true` constraint |
|
873
|
+
|
874
|
+
## Nullable Properties
|
875
|
+
|
876
|
+
A **nullable** property can contain a `null` value, but the property itself must still be present in the object:
|
877
|
+
|
878
|
+
```ruby
|
879
|
+
property :age, T.nilable(Integer)
|
880
|
+
```
|
881
|
+
|
882
|
+
This produces the following JSON Schema:
|
883
|
+
|
884
|
+
```json
|
885
|
+
{
|
886
|
+
"properties": {
|
887
|
+
"age": { "type": ["integer", "null"] }
|
888
|
+
},
|
889
|
+
"required": ["age"]
|
890
|
+
}
|
891
|
+
```
|
892
|
+
|
893
|
+
In this case, the following data would be valid:
|
894
|
+
- `{ "age": 25 }`
|
895
|
+
- `{ "age": null }`
|
896
|
+
|
897
|
+
But this would be invalid:
|
898
|
+
- `{ }` (missing the age property entirely)
|
899
|
+
|
900
|
+
## Optional Properties
|
901
|
+
|
902
|
+
An **optional** property doesn't have to be present in the object at all:
|
903
|
+
|
904
|
+
```ruby
|
905
|
+
property :nickname, String, optional: true
|
906
|
+
```
|
907
|
+
|
908
|
+
This produces:
|
909
|
+
|
910
|
+
```json
|
911
|
+
{
|
912
|
+
"properties": {
|
913
|
+
"nickname": { "type": "string" }
|
914
|
+
}
|
915
|
+
// Note: "nickname" is not in the "required" array
|
916
|
+
}
|
917
|
+
```
|
918
|
+
|
919
|
+
In this case, the following data would be valid:
|
920
|
+
- `{ "nickname": "Joe" }`
|
921
|
+
- `{ }` (omitting nickname entirely)
|
922
|
+
|
923
|
+
But this would be invalid:
|
924
|
+
- `{ "nickname": null }` (null is not allowed because the property isn't nullable)
|
925
|
+
|
926
|
+
## Nullable AND Optional Properties
|
927
|
+
|
928
|
+
For properties that should be both nullable and optional (can be omitted or null), you need to combine both approaches:
|
929
|
+
|
930
|
+
```ruby
|
931
|
+
property :bio, T.nilable(String), optional: true
|
932
|
+
```
|
933
|
+
|
934
|
+
This produces:
|
935
|
+
|
936
|
+
```json
|
937
|
+
{
|
938
|
+
"properties": {
|
939
|
+
"bio": { "type": ["string", "null"] }
|
940
|
+
}
|
941
|
+
// Note: "bio" is not in the "required" array
|
942
|
+
}
|
943
|
+
```
|
944
|
+
|
945
|
+
For convenience, EasyTalk also provides a helper method:
|
946
|
+
|
947
|
+
```ruby
|
948
|
+
nullable_optional_property :bio, String
|
949
|
+
```
|
950
|
+
|
951
|
+
Which is equivalent to the above.
|
952
|
+
|
953
|
+
## Configuration Options
|
954
|
+
|
955
|
+
By default, nullable properties are still required. You can change this global behavior:
|
956
|
+
|
957
|
+
```ruby
|
958
|
+
EasyTalk.configure do |config|
|
959
|
+
config.nilable_is_optional = true # Makes all T.nilable properties also optional
|
960
|
+
end
|
961
|
+
```
|
962
|
+
|
963
|
+
With this configuration, any property defined with `T.nilable(Type)` will be treated as both nullable and optional.
|
964
|
+
|
965
|
+
## Practical Examples
|
966
|
+
|
967
|
+
### User Profile Schema
|
968
|
+
|
969
|
+
```ruby
|
970
|
+
class UserProfile
|
971
|
+
include EasyTalk::Model
|
972
|
+
|
973
|
+
define_schema do
|
974
|
+
# Required properties (must exist, cannot be null)
|
975
|
+
property :id, String
|
976
|
+
property :name, String
|
977
|
+
|
978
|
+
# Required but nullable (must exist, can be null)
|
979
|
+
property :age, T.nilable(Integer)
|
980
|
+
|
981
|
+
# Optional but not nullable (can be omitted, cannot be null if present)
|
982
|
+
property :email, String, optional: true
|
983
|
+
|
984
|
+
# Optional and nullable (can be omitted, can be null if present)
|
985
|
+
nullable_optional_property :bio, String
|
986
|
+
|
987
|
+
# Nested object with mixed property types
|
988
|
+
property :address, Hash do
|
989
|
+
property :street, String # Required
|
990
|
+
property :city, String # Required
|
991
|
+
property :state, String, optional: true # Optional
|
992
|
+
nullable_optional_property :zip, String # Optional and nullable
|
993
|
+
end
|
994
|
+
end
|
995
|
+
end
|
996
|
+
```
|
997
|
+
|
998
|
+
This creates clear expectations for data validation:
|
999
|
+
- `id` and `name` must be present and cannot be null
|
1000
|
+
- `age` must be present but can be null
|
1001
|
+
- `email` doesn't have to be present, but if it is, it cannot be null
|
1002
|
+
- `bio` doesn't have to be present, and if it is, it can be null
|
1003
|
+
|
1004
|
+
## Common Gotchas
|
1005
|
+
|
1006
|
+
### Misconception: Nullable Implies Optional
|
1007
|
+
|
1008
|
+
A common mistake is assuming that `T.nilable(Type)` makes a property optional. By default, it only allows the property to have a null value - the property itself is still required to exist in the object.
|
1009
|
+
|
1010
|
+
### Misconception: Optional Properties Accept Null
|
1011
|
+
|
1012
|
+
An optional property (defined with `optional: true`) can be omitted entirely, but if it is present, it must conform to its type constraint. If you want to allow null values, you must also make it nullable with `T.nilable(Type)`.
|
1013
|
+
|
1014
|
+
## Migration from Earlier Versions
|
1015
|
+
|
1016
|
+
If you're upgrading from EasyTalk version 1.0.1 or earlier, be aware that the handling of nullable vs optional properties has been improved for clarity.
|
1017
|
+
|
1018
|
+
To maintain backward compatibility with your existing code, you can use:
|
1019
|
+
|
1020
|
+
```ruby
|
1021
|
+
EasyTalk.configure do |config|
|
1022
|
+
config.nilable_is_optional = true # Makes T.nilable properties behave as they did before
|
1023
|
+
end
|
1024
|
+
```
|
1025
|
+
|
1026
|
+
We recommend updating your schema definitions to explicitly declare which properties are optional using the `optional: true` constraint, as this makes your intent clearer.
|
1027
|
+
|
1028
|
+
## Best Practices
|
1029
|
+
|
1030
|
+
1. **Be explicit about intent**: Always clarify whether properties should be nullable, optional, or both
|
1031
|
+
2. **Use the helper method**: For properties that are both nullable and optional, use `nullable_optional_property`
|
1032
|
+
3. **Document expectations**: Use comments to clarify validation requirements for complex schemas
|
1033
|
+
4. **Consider validation implications**: Remember that ActiveModel validations operate independently of the schema definition
|
1034
|
+
|
1035
|
+
## JSON Schema Comparison
|
1036
|
+
|
1037
|
+
| EasyTalk Definition | Required | Nullable | JSON Schema Equivalent |
|
1038
|
+
|--------------------|----------|----------|------------------------|
|
1039
|
+
| `property :p, String` | Yes | No | `{ "properties": { "p": { "type": "string" } }, "required": ["p"] }` |
|
1040
|
+
| `property :p, T.nilable(String)` | Yes | Yes | `{ "properties": { "p": { "type": ["string", "null"] } }, "required": ["p"] }` |
|
1041
|
+
| `property :p, String, optional: true` | No | No | `{ "properties": { "p": { "type": "string" } } }` |
|
1042
|
+
| `nullable_optional_property :p, String` | No | Yes | `{ "properties": { "p": { "type": ["string", "null"] } } }` |
|
1043
|
+
|
863
1044
|
## Development and Contributing
|
864
1045
|
|
865
1046
|
### Setting Up the Development Environment
|
@@ -98,6 +98,9 @@ module EasyTalk
|
|
98
98
|
# Map the database type to Ruby type
|
99
99
|
ruby_type = COLUMN_TYPE_MAP.fetch(column.type, String)
|
100
100
|
|
101
|
+
# If the column is nullable, wrap the type in a Union with NilClass
|
102
|
+
ruby_type = T::Types::Union.new([ruby_type, NilClass]) if column.null
|
103
|
+
|
101
104
|
# Build constraints hash for this column
|
102
105
|
constraints = build_column_constraints(column, column_enhancements)
|
103
106
|
|
@@ -60,6 +60,18 @@ module EasyTalk
|
|
60
60
|
def items
|
61
61
|
@type.items
|
62
62
|
end
|
63
|
+
|
64
|
+
# Builder class for AllOf composition.
|
65
|
+
class AllOfBuilder < CompositionBuilder
|
66
|
+
end
|
67
|
+
|
68
|
+
# Builder class for AnyOf composition.
|
69
|
+
class AnyOfBuilder < CompositionBuilder
|
70
|
+
end
|
71
|
+
|
72
|
+
# Builder class for OneOf composition.
|
73
|
+
class OneOfBuilder < CompositionBuilder
|
74
|
+
end
|
63
75
|
end
|
64
76
|
end
|
65
77
|
end
|
@@ -118,6 +118,11 @@ module EasyTalk
|
|
118
118
|
# Check constraints[:optional]
|
119
119
|
return true if prop_options.dig(:constraints, :optional)
|
120
120
|
|
121
|
+
# Check for nil_optional config to determine if nilable should also mean optional
|
122
|
+
if prop_options[:type].respond_to?(:nilable?) && prop_options[:type].nilable?
|
123
|
+
return EasyTalk.configuration.nilable_is_optional
|
124
|
+
end
|
125
|
+
|
121
126
|
false
|
122
127
|
end
|
123
128
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'string_builder'
|
4
|
+
|
5
|
+
module EasyTalk
|
6
|
+
module Builders
|
7
|
+
# Builder class for temporal properties (date, datetime, time).
|
8
|
+
class TemporalBuilder < StringBuilder
|
9
|
+
# Initializes a new instance of the TemporalBuilder class.
|
10
|
+
#
|
11
|
+
# @param property_name [Symbol] The name of the property.
|
12
|
+
# @param options [Hash] The options for the builder.
|
13
|
+
# @param format [String] The format of the temporal property (date, date-time, time).
|
14
|
+
def initialize(property_name, options = {}, format = nil)
|
15
|
+
super(property_name, options)
|
16
|
+
@format = format
|
17
|
+
end
|
18
|
+
|
19
|
+
# Modifies the schema to include the format constraint for a temporal property.
|
20
|
+
sig { returns(T::Hash[Symbol, T.untyped]) }
|
21
|
+
def schema
|
22
|
+
super.tap do |schema|
|
23
|
+
schema[:format] = @format if @format
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Builder class for date properties.
|
28
|
+
class DateBuilder < TemporalBuilder
|
29
|
+
def initialize(property_name, options = {})
|
30
|
+
super(property_name, options, 'date')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Builder class for datetime properties.
|
35
|
+
class DatetimeBuilder < TemporalBuilder
|
36
|
+
def initialize(property_name, options = {})
|
37
|
+
super(property_name, options, 'date-time')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Builder class for time properties.
|
42
|
+
class TimeBuilder < TemporalBuilder
|
43
|
+
def initialize(property_name, options = {})
|
44
|
+
super(property_name, options, 'time')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module EasyTalk
|
4
4
|
class Configuration
|
5
5
|
attr_accessor :exclude_foreign_keys, :exclude_associations, :excluded_columns,
|
6
|
-
:exclude_primary_key, :exclude_timestamps, :default_additional_properties
|
6
|
+
:exclude_primary_key, :exclude_timestamps, :default_additional_properties,
|
7
|
+
:nilable_is_optional
|
7
8
|
|
8
9
|
def initialize
|
9
10
|
@exclude_foreign_keys = true
|
@@ -12,6 +13,7 @@ module EasyTalk
|
|
12
13
|
@exclude_primary_key = true # New option, defaulting to true
|
13
14
|
@exclude_timestamps = true # New option, defaulting to true
|
14
15
|
@default_additional_properties = false
|
16
|
+
@nilable_is_optional = false
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
data/lib/easy_talk/property.rb
CHANGED
@@ -6,12 +6,8 @@ require_relative 'builders/number_builder'
|
|
6
6
|
require_relative 'builders/boolean_builder'
|
7
7
|
require_relative 'builders/null_builder'
|
8
8
|
require_relative 'builders/string_builder'
|
9
|
-
require_relative 'builders/
|
10
|
-
require_relative 'builders/
|
11
|
-
require_relative 'builders/time_builder'
|
12
|
-
require_relative 'builders/any_of_builder'
|
13
|
-
require_relative 'builders/all_of_builder'
|
14
|
-
require_relative 'builders/one_of_builder'
|
9
|
+
require_relative 'builders/temporal_builder'
|
10
|
+
require_relative 'builders/composition_builder'
|
15
11
|
require_relative 'builders/typed_array_builder'
|
16
12
|
require_relative 'builders/union_builder'
|
17
13
|
|
@@ -40,12 +36,12 @@ module EasyTalk
|
|
40
36
|
'BigDecimal' => Builders::NumberBuilder,
|
41
37
|
'T::Boolean' => Builders::BooleanBuilder,
|
42
38
|
'NilClass' => Builders::NullBuilder,
|
43
|
-
'Date' => Builders::DateBuilder,
|
44
|
-
'DateTime' => Builders::DatetimeBuilder,
|
45
|
-
'Time' => Builders::TimeBuilder,
|
46
|
-
'anyOf' => Builders::AnyOfBuilder,
|
47
|
-
'allOf' => Builders::AllOfBuilder,
|
48
|
-
'oneOf' => Builders::OneOfBuilder,
|
39
|
+
'Date' => Builders::TemporalBuilder::DateBuilder,
|
40
|
+
'DateTime' => Builders::TemporalBuilder::DatetimeBuilder,
|
41
|
+
'Time' => Builders::TemporalBuilder::TimeBuilder,
|
42
|
+
'anyOf' => Builders::CompositionBuilder::AnyOfBuilder,
|
43
|
+
'allOf' => Builders::CompositionBuilder::AllOfBuilder,
|
44
|
+
'oneOf' => Builders::CompositionBuilder::OneOfBuilder,
|
49
45
|
'T::Types::TypedArray' => Builders::TypedArrayBuilder,
|
50
46
|
'T::Types::Union' => Builders::UnionBuilder
|
51
47
|
}.freeze
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'keywords'
|
4
|
+
require_relative 'types/composer'
|
4
5
|
|
5
6
|
module EasyTalk
|
6
7
|
#
|
@@ -64,5 +65,21 @@ module EasyTalk
|
|
64
65
|
def optional?
|
65
66
|
@schema[:optional]
|
66
67
|
end
|
68
|
+
|
69
|
+
# Helper method for nullable and optional properties
|
70
|
+
def nullable_optional_property(name, type, constraints = {}, &blk)
|
71
|
+
# Ensure type is nilable
|
72
|
+
nilable_type = if type.respond_to?(:nilable?) && type.nilable?
|
73
|
+
type
|
74
|
+
else
|
75
|
+
T.nilable(type)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Ensure constraints include optional: true
|
79
|
+
constraints = constraints.merge(optional: true)
|
80
|
+
|
81
|
+
# Call standard property method
|
82
|
+
property(name, nilable_type, constraints, &blk)
|
83
|
+
end
|
67
84
|
end
|
68
85
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_composer'
|
4
|
+
|
5
|
+
module EasyTalk
|
6
|
+
module Types
|
7
|
+
# Base class for composition types
|
8
|
+
class Composer < BaseComposer
|
9
|
+
# Returns the name of the composition type.
|
10
|
+
def self.name
|
11
|
+
raise NotImplementedError, "#{self.class.name} must implement the name method"
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the name of the composition type.
|
15
|
+
def name
|
16
|
+
self.class.name
|
17
|
+
end
|
18
|
+
|
19
|
+
# Represents a composition type that allows all of the specified types.
|
20
|
+
class AllOf < Composer
|
21
|
+
def self.name
|
22
|
+
:allOf
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
:allOf
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Represents a composition type that allows any of the specified types.
|
31
|
+
class AnyOf < Composer
|
32
|
+
def self.name
|
33
|
+
:anyOf
|
34
|
+
end
|
35
|
+
|
36
|
+
def name
|
37
|
+
:anyOf
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Represents a composition type that allows one of the specified types.
|
42
|
+
class OneOf < Composer
|
43
|
+
def self.name
|
44
|
+
:oneOf
|
45
|
+
end
|
46
|
+
|
47
|
+
def name
|
48
|
+
:oneOf
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Shorthand module for accessing the AllOf composer
|
56
|
+
module T
|
57
|
+
module AllOf
|
58
|
+
# Creates a new instance of `EasyTalk::Types::Composer::AllOf` with the given arguments.
|
59
|
+
#
|
60
|
+
# @param args [Array] the list of arguments to be passed to the constructor
|
61
|
+
# @return [EasyTalk::Types::Composer::AllOf] a new instance
|
62
|
+
def self.[](*args)
|
63
|
+
EasyTalk::Types::Composer::AllOf.new(*args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Shorthand module for accessing the AnyOf composer
|
68
|
+
module AnyOf
|
69
|
+
# Creates a new instance of `EasyTalk::Types::Composer::AnyOf` with the given arguments.
|
70
|
+
#
|
71
|
+
# @param args [Array] the list of arguments to be passed to the constructor
|
72
|
+
# @return [EasyTalk::Types::Composer::AnyOf] a new instance
|
73
|
+
def self.[](*args)
|
74
|
+
EasyTalk::Types::Composer::AnyOf.new(*args)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Shorthand module for accessing the OneOf composer
|
79
|
+
module OneOf
|
80
|
+
# Creates a new instance of `EasyTalk::Types::Composer::OneOf` with the given arguments.
|
81
|
+
#
|
82
|
+
# @param args [Array] the list of arguments to be passed to the constructor
|
83
|
+
# @return [EasyTalk::Types::Composer::OneOf] a new instance
|
84
|
+
def self.[](*args)
|
85
|
+
EasyTalk::Types::Composer::OneOf.new(*args)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/easy_talk/version.rb
CHANGED
data/lib/easy_talk.rb
CHANGED
@@ -7,9 +7,7 @@ module EasyTalk
|
|
7
7
|
require 'easy_talk/errors'
|
8
8
|
require 'easy_talk/errors_helper'
|
9
9
|
require 'easy_talk/configuration'
|
10
|
-
require 'easy_talk/types/
|
11
|
-
require 'easy_talk/types/all_of'
|
12
|
-
require 'easy_talk/types/one_of'
|
10
|
+
require 'easy_talk/types/composer'
|
13
11
|
require 'easy_talk/model'
|
14
12
|
require 'easy_talk/property'
|
15
13
|
require 'easy_talk/schema_definition'
|
@@ -24,4 +22,8 @@ module EasyTalk
|
|
24
22
|
ErrorHelper.raise_unknown_option_error(property_name: property_name, option: options, valid_options: valid_keys)
|
25
23
|
end
|
26
24
|
end
|
25
|
+
|
26
|
+
def self.configure_nilable_behavior(nilable_is_optional = false)
|
27
|
+
configuration.nilable_is_optional = nilable_is_optional
|
28
|
+
end
|
27
29
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_talk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergio Bayona
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-03-
|
10
|
+
date: 2025-03-12 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activemodel
|
@@ -213,21 +213,16 @@ files:
|
|
213
213
|
- docs/index.markdown
|
214
214
|
- lib/easy_talk.rb
|
215
215
|
- lib/easy_talk/active_record_schema_builder.rb
|
216
|
-
- lib/easy_talk/builders/all_of_builder.rb
|
217
|
-
- lib/easy_talk/builders/any_of_builder.rb
|
218
216
|
- lib/easy_talk/builders/base_builder.rb
|
219
217
|
- lib/easy_talk/builders/boolean_builder.rb
|
220
218
|
- lib/easy_talk/builders/collection_helpers.rb
|
221
219
|
- lib/easy_talk/builders/composition_builder.rb
|
222
|
-
- lib/easy_talk/builders/date_builder.rb
|
223
|
-
- lib/easy_talk/builders/datetime_builder.rb
|
224
220
|
- lib/easy_talk/builders/integer_builder.rb
|
225
221
|
- lib/easy_talk/builders/null_builder.rb
|
226
222
|
- lib/easy_talk/builders/number_builder.rb
|
227
223
|
- lib/easy_talk/builders/object_builder.rb
|
228
|
-
- lib/easy_talk/builders/one_of_builder.rb
|
229
224
|
- lib/easy_talk/builders/string_builder.rb
|
230
|
-
- lib/easy_talk/builders/
|
225
|
+
- lib/easy_talk/builders/temporal_builder.rb
|
231
226
|
- lib/easy_talk/builders/typed_array_builder.rb
|
232
227
|
- lib/easy_talk/builders/union_builder.rb
|
233
228
|
- lib/easy_talk/configuration.rb
|
@@ -239,10 +234,8 @@ files:
|
|
239
234
|
- lib/easy_talk/schema_definition.rb
|
240
235
|
- lib/easy_talk/sorbet_extension.rb
|
241
236
|
- lib/easy_talk/tools/function_builder.rb
|
242
|
-
- lib/easy_talk/types/all_of.rb
|
243
|
-
- lib/easy_talk/types/any_of.rb
|
244
237
|
- lib/easy_talk/types/base_composer.rb
|
245
|
-
- lib/easy_talk/types/
|
238
|
+
- lib/easy_talk/types/composer.rb
|
246
239
|
- lib/easy_talk/version.rb
|
247
240
|
homepage: https://github.com/sergiobayona/easy_talk
|
248
241
|
licenses:
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_builder'
|
4
|
-
|
5
|
-
module EasyTalk
|
6
|
-
module Builders
|
7
|
-
# Builder class for date properties.
|
8
|
-
class DateBuilder < StringBuilder
|
9
|
-
# Modifies the schema to include the format constraint for a date property.
|
10
|
-
sig { returns(T::Hash[Symbol, T.untyped]) }
|
11
|
-
def schema
|
12
|
-
super.tap do |schema|
|
13
|
-
schema[:format] = 'date'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_builder'
|
4
|
-
|
5
|
-
module EasyTalk
|
6
|
-
module Builders
|
7
|
-
# Builder class for datetime properties.
|
8
|
-
class DatetimeBuilder < StringBuilder
|
9
|
-
# Modifies the schema to include the format constraint for a datetime property.
|
10
|
-
sig { returns(T::Hash[Symbol, T.untyped]) }
|
11
|
-
def schema
|
12
|
-
super.tap do |schema|
|
13
|
-
schema[:format] = 'date-time'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_builder'
|
4
|
-
|
5
|
-
module EasyTalk
|
6
|
-
module Builders
|
7
|
-
# Builder class for time properties.
|
8
|
-
class TimeBuilder < StringBuilder
|
9
|
-
def schema
|
10
|
-
super.tap do |schema|
|
11
|
-
schema[:format] = 'time'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_composer'
|
4
|
-
# The EasyTalk module provides a collection of types for composing schemas.
|
5
|
-
module EasyTalk
|
6
|
-
# The `Types` module provides a collection of classes for composing different types.
|
7
|
-
module Types
|
8
|
-
# Represents a composition type that allows all of the specified types.
|
9
|
-
class AllOf < BaseComposer
|
10
|
-
def self.name
|
11
|
-
:allOf
|
12
|
-
end
|
13
|
-
|
14
|
-
def name
|
15
|
-
:allOf
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
module T
|
22
|
-
# no-doc
|
23
|
-
module AllOf
|
24
|
-
# Creates a new instance of `EasyTalk::Types::AllOf` with the given arguments.
|
25
|
-
#
|
26
|
-
# @param args [Array] the list of arguments to be passed to the `EasyTalk::Types::AllOf` constructor
|
27
|
-
# @return [EasyTalk::Types::AllOf] a new instance of `EasyTalk::Types::AllOf`
|
28
|
-
def self.[](*args)
|
29
|
-
EasyTalk::Types::AllOf.new(*args)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_composer'
|
4
|
-
module EasyTalk
|
5
|
-
module Types
|
6
|
-
# The `Types` module provides a collection of composers for defining different types.
|
7
|
-
#
|
8
|
-
# This module contains composers for various types such as `AnyOf`, `AllOf`, etc.
|
9
|
-
# Each composer is responsible for defining the behavior and properties of its respective type.
|
10
|
-
class AnyOf < BaseComposer
|
11
|
-
# Returns the name of the AnyOf composer.
|
12
|
-
#
|
13
|
-
# @return [Symbol] The name of the composer.
|
14
|
-
def self.name
|
15
|
-
:anyOf
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns the name of the AnyOf composer.
|
19
|
-
#
|
20
|
-
# @return [Symbol] The name of the composer.
|
21
|
-
def name
|
22
|
-
:anyOf
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module T
|
29
|
-
# no-doc
|
30
|
-
module AnyOf
|
31
|
-
# Creates a new instance of `EasyTalk::Types::AnyOf` with the given arguments.
|
32
|
-
#
|
33
|
-
# @param args [Array] the list of arguments to be passed to the `EasyTalk::Types::AnyOf` constructor
|
34
|
-
# @return [EasyTalk::Types::AnyOf] a new instance of `EasyTalk::Types::AnyOf`
|
35
|
-
def self.[](*args)
|
36
|
-
EasyTalk::Types::AnyOf.new(*args)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base_composer'
|
4
|
-
module EasyTalk
|
5
|
-
module Types
|
6
|
-
# Represents a composition type that allows one of the specified types.
|
7
|
-
class OneOf < BaseComposer
|
8
|
-
# Returns the name of the composition type.
|
9
|
-
def self.name
|
10
|
-
:oneOf
|
11
|
-
end
|
12
|
-
|
13
|
-
# Returns the name of the composition type.
|
14
|
-
def name
|
15
|
-
:oneOf
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
module T
|
22
|
-
# Creates a new instance of `EasyTalk::Types::OneOf` with the given arguments.
|
23
|
-
#
|
24
|
-
# @param args [Array] the list of arguments to be passed to the `EasyTalk::Types::OneOf` constructor
|
25
|
-
# @return [EasyTalk::Types::OneOf] a new instance of `EasyTalk::Types::OneOf`
|
26
|
-
module OneOf
|
27
|
-
def self.[](*args)
|
28
|
-
EasyTalk::Types::OneOf.new(*args)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|