easy_talk 3.1.0 → 3.3.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -39
- data/.yardopts +13 -0
- data/CHANGELOG.md +164 -0
- data/README.md +442 -1529
- data/Rakefile +27 -0
- data/docs/.gitignore +1 -0
- data/docs/about.markdown +28 -8
- data/docs/getting-started.markdown +102 -0
- data/docs/index.markdown +51 -4
- data/docs/json_schema_compliance.md +169 -0
- data/docs/nested-models.markdown +216 -0
- data/docs/primitive-schema-rfc.md +894 -0
- data/docs/property-types.markdown +212 -0
- data/docs/schema-definition.markdown +180 -0
- data/lib/easy_talk/builders/base_builder.rb +6 -3
- data/lib/easy_talk/builders/boolean_builder.rb +2 -1
- data/lib/easy_talk/builders/collection_helpers.rb +4 -0
- data/lib/easy_talk/builders/composition_builder.rb +16 -13
- data/lib/easy_talk/builders/integer_builder.rb +2 -1
- data/lib/easy_talk/builders/null_builder.rb +4 -1
- data/lib/easy_talk/builders/number_builder.rb +4 -1
- data/lib/easy_talk/builders/object_builder.rb +109 -33
- data/lib/easy_talk/builders/registry.rb +182 -0
- data/lib/easy_talk/builders/string_builder.rb +3 -1
- data/lib/easy_talk/builders/temporal_builder.rb +7 -0
- data/lib/easy_talk/builders/tuple_builder.rb +89 -0
- data/lib/easy_talk/builders/typed_array_builder.rb +19 -6
- data/lib/easy_talk/builders/union_builder.rb +5 -1
- data/lib/easy_talk/configuration.rb +47 -2
- data/lib/easy_talk/error_formatter/base.rb +100 -0
- data/lib/easy_talk/error_formatter/error_code_mapper.rb +82 -0
- data/lib/easy_talk/error_formatter/flat.rb +38 -0
- data/lib/easy_talk/error_formatter/json_pointer.rb +38 -0
- data/lib/easy_talk/error_formatter/jsonapi.rb +64 -0
- data/lib/easy_talk/error_formatter/path_converter.rb +53 -0
- data/lib/easy_talk/error_formatter/rfc7807.rb +69 -0
- data/lib/easy_talk/error_formatter.rb +143 -0
- data/lib/easy_talk/errors.rb +3 -0
- data/lib/easy_talk/errors_helper.rb +66 -34
- data/lib/easy_talk/json_schema_equality.rb +46 -0
- data/lib/easy_talk/keywords.rb +0 -1
- data/lib/easy_talk/model.rb +148 -89
- data/lib/easy_talk/model_helper.rb +17 -0
- data/lib/easy_talk/naming_strategies.rb +24 -0
- data/lib/easy_talk/property.rb +23 -94
- data/lib/easy_talk/ref_helper.rb +33 -0
- data/lib/easy_talk/schema.rb +199 -0
- data/lib/easy_talk/schema_definition.rb +57 -5
- data/lib/easy_talk/schema_methods.rb +111 -0
- data/lib/easy_talk/sorbet_extension.rb +1 -0
- data/lib/easy_talk/tools/function_builder.rb +1 -1
- data/lib/easy_talk/type_introspection.rb +222 -0
- data/lib/easy_talk/types/base_composer.rb +2 -1
- data/lib/easy_talk/types/composer.rb +4 -0
- data/lib/easy_talk/types/tuple.rb +77 -0
- data/lib/easy_talk/validation_adapters/active_model_adapter.rb +617 -0
- data/lib/easy_talk/validation_adapters/active_model_schema_validation.rb +106 -0
- data/lib/easy_talk/validation_adapters/base.rb +156 -0
- data/lib/easy_talk/validation_adapters/none_adapter.rb +45 -0
- data/lib/easy_talk/validation_adapters/registry.rb +87 -0
- data/lib/easy_talk/validation_builder.rb +29 -309
- data/lib/easy_talk/version.rb +1 -1
- data/lib/easy_talk.rb +42 -0
- metadata +38 -7
- data/docs/404.html +0 -25
- data/docs/_posts/2024-05-07-welcome-to-jekyll.markdown +0 -29
- data/easy_talk.gemspec +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f11b7be6e0fa32087d5be57be3d3e37d5bd5b96cc61ae8626b33d41a420e401
|
|
4
|
+
data.tar.gz: 82ba98f220e8e75e3bb3e208a595a168f188c226a130e88f13991da9a386cfc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90fb93ef486adb8151e883e6929437be2f52bdbe4a51bb45485006884a983b80ce9f10de1d14b313031be4b8126d6fe21c3bd54a998863543a1be1d752c124d9
|
|
7
|
+
data.tar.gz: 2ff9102ba57ae6738cb79511fdd095b5f798a760c009b10d2b5577c30575f04d94dfb11e410036e566971d92e27e2c4bc2d17336e44c64f9d35b966bbe1b4960
|
data/.rubocop.yml
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
plugins:
|
|
2
|
-
- rubocop-rspec
|
|
3
|
-
- rubocop-rake
|
|
4
|
-
|
|
5
1
|
AllCops:
|
|
6
2
|
NewCops: enable
|
|
7
3
|
TargetRubyVersion: 3.2
|
|
@@ -33,6 +29,8 @@ Style/StringLiterals:
|
|
|
33
29
|
|
|
34
30
|
Metrics/ClassLength:
|
|
35
31
|
Max: 240
|
|
32
|
+
Exclude:
|
|
33
|
+
- lib/easy_talk/validation_adapters/active_model_adapter.rb
|
|
36
34
|
|
|
37
35
|
Metrics/MethodLength:
|
|
38
36
|
Max: 60
|
|
@@ -55,6 +53,7 @@ Metrics/BlockNesting:
|
|
|
55
53
|
Metrics/BlockLength:
|
|
56
54
|
Exclude:
|
|
57
55
|
- spec/**/*
|
|
56
|
+
- easy_talk.gemspec
|
|
58
57
|
|
|
59
58
|
Layout/EndAlignment:
|
|
60
59
|
Enabled: false
|
|
@@ -70,47 +69,24 @@ Lint/EmptyBlock:
|
|
|
70
69
|
Exclude:
|
|
71
70
|
- spec/**/*
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
Enabled: false
|
|
75
|
-
|
|
76
|
-
RSpec/LeakyConstantDeclaration:
|
|
77
|
-
Enabled: false
|
|
78
|
-
|
|
79
|
-
RSpec/RemoveConst:
|
|
80
|
-
Enabled: false
|
|
81
|
-
|
|
82
|
-
RSpec/BeforeAfterAll:
|
|
83
|
-
Enabled: false
|
|
84
|
-
|
|
85
|
-
RSpec/NestedGroups:
|
|
86
|
-
Max: 4
|
|
87
|
-
|
|
88
|
-
RSpec/RepeatedDescription:
|
|
89
|
-
Enabled: false
|
|
90
|
-
|
|
91
|
-
RSpec/PendingWithoutReason:
|
|
92
|
-
Enabled: false
|
|
93
|
-
|
|
94
|
-
RSpec/MultipleDescribes:
|
|
72
|
+
Lint/DuplicateBranch:
|
|
95
73
|
Enabled: false
|
|
96
74
|
|
|
97
|
-
|
|
75
|
+
Gemspec/DevelopmentDependencies:
|
|
98
76
|
Enabled: false
|
|
99
77
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
RSpec/ExampleLength:
|
|
104
|
-
Max: 40
|
|
105
|
-
|
|
106
|
-
RSpec/MultipleExpectations:
|
|
107
|
-
Max: 10
|
|
78
|
+
Naming/PredicateMethod:
|
|
79
|
+
Exclude:
|
|
80
|
+
- spec/support/schema_validation_matcher.rb
|
|
108
81
|
|
|
109
|
-
|
|
82
|
+
Naming/BlockForwarding:
|
|
110
83
|
Enabled: false
|
|
111
84
|
|
|
112
|
-
Lint/
|
|
113
|
-
|
|
85
|
+
Lint/UnusedMethodArgument:
|
|
86
|
+
AllowUnusedKeywordArguments: true
|
|
87
|
+
Exclude:
|
|
88
|
+
- lib/easy_talk/configuration.rb
|
|
89
|
+
- lib/easy_talk/schema_definition.rb
|
|
114
90
|
|
|
115
|
-
|
|
91
|
+
Style/DefWithParentheses:
|
|
116
92
|
Enabled: false
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,167 @@
|
|
|
1
|
+
## [3.3.0] - 2026-01-12
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- **Schema Objects in additionalProperties**: Extended `additionalProperties` to support type constraints and schema objects (#160)
|
|
6
|
+
- New syntax: `additional_properties Integer, minimum: 0, maximum: 100`
|
|
7
|
+
- Three supported forms: boolean, type class, or type with constraints
|
|
8
|
+
- Generates full JSON Schema for additional properties validation
|
|
9
|
+
- New methods: `ObjectBuilder#process_additional_properties`, `ObjectBuilder#build_additional_properties_schema`
|
|
10
|
+
- Fully backwards compatible with existing boolean usage
|
|
11
|
+
|
|
12
|
+
- **External $ref Support via $id**: Enhanced schema referencing with external URI support (#158)
|
|
13
|
+
- New configuration options:
|
|
14
|
+
- `base_schema_uri` - Base URI for auto-generating $id values
|
|
15
|
+
- `auto_generate_ids` - Enable automatic $id generation (default: false)
|
|
16
|
+
- `prefer_external_refs` - Use external URI in $ref when model has $id (default: false)
|
|
17
|
+
- Three-level schema ID resolution: explicit per-model → auto-generated → global
|
|
18
|
+
- Dynamic $ref templates conditionally use external URIs or local `#/$defs/ModelName` format
|
|
19
|
+
- Supports composition types (T::OneOf, T::AnyOf, T::AllOf) with external refs
|
|
20
|
+
|
|
21
|
+
- **T::Tuple Type for Positional Array Validation**: New tuple type for JSON Schema tuple support (#154, #155)
|
|
22
|
+
- New syntax: `property :coords, T::Tuple[Float, Float]`
|
|
23
|
+
- Generates JSON Schema with `items` as array of schemas
|
|
24
|
+
- Supports `additional_items: false`, `true`, or a type constraint
|
|
25
|
+
- Combines with array constraints: `min_items`, `max_items`, `unique_items`
|
|
26
|
+
- ActiveModel validation for runtime type checking at each position
|
|
27
|
+
- New files: `lib/easy_talk/types/tuple.rb`, `lib/easy_talk/builders/tuple_builder.rb`
|
|
28
|
+
|
|
29
|
+
- **Object-Level JSON Schema Keywords**: Support for schema-wide object constraints (#148, #151)
|
|
30
|
+
- New keywords: `patternProperties`, `minProperties`, `maxProperties`, `dependencies`, `dependentRequired`
|
|
31
|
+
- ActiveModel validators for object-level constraints via `ActiveModelSchemaValidation` module
|
|
32
|
+
- Auto-defined `count_present_properties` private method on model classes
|
|
33
|
+
- Thread-safe validator application with double-checked locking
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- **Format Validation Enhancements**: Improved format validation accuracy and security (#157, #156, #144)
|
|
38
|
+
- **Scope Fix**: Format and pattern validations now only apply to string values (per JSON Schema spec)
|
|
39
|
+
- **URI/URL Validation**: Uses `URI.parse()` with `.absolute?` check instead of regex
|
|
40
|
+
- **Parsing-Based Validators**: Date, DateTime, and Time formats now use parsing instead of regex
|
|
41
|
+
- **Email Validation**: Replaced ReDoS-vulnerable regex with simple linear-time pattern
|
|
42
|
+
- New validation methods: `apply_uri_format_validation`, `apply_date_format_validation`, `apply_datetime_format_validation`, `apply_time_format_validation`
|
|
43
|
+
|
|
44
|
+
- **JSON Schema Equality for uniqueItems**: Implements correct JSON Schema equality semantics for array uniqueness (#152)
|
|
45
|
+
- Objects with same keys/values in different order are equal
|
|
46
|
+
- Numbers are mathematically equal (1 == 1.0)
|
|
47
|
+
- Type matters for non-numbers (true != 1, false != 0)
|
|
48
|
+
- New module: `EasyTalk::JsonSchemaEquality` with `normalize()` and `duplicates?()` methods
|
|
49
|
+
- MAX_DEPTH = 100 limit to prevent SystemStackError on deeply nested structures
|
|
50
|
+
|
|
51
|
+
- **Array Presence Validation**: Required array properties now properly reject nil values (#140)
|
|
52
|
+
- New method: `apply_array_presence_validation()` for array-specific nil checks
|
|
53
|
+
- Rejects nil but allows empty arrays `[]`
|
|
54
|
+
- Aligns with JSON Schema spec: 'optional' means property can be omitted, not that nil is accepted
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- **Default Additional Properties Configuration**: Fixed `default_additional_properties` config option being ignored (#142)
|
|
59
|
+
- Both `ObjectBuilder` and `SchemaDefinition` now use configured default
|
|
60
|
+
- Added schema hash duplication to prevent mutation side effects
|
|
61
|
+
|
|
62
|
+
- **Property Name Validation**: Fixed validation incorrectly applying to JSON output name (`:as` constraint) instead of Ruby property name (#143)
|
|
63
|
+
- `validate_property_name()` now validates Ruby name only
|
|
64
|
+
- Allows using `:as` for JSON-LD (@type, @id), JSON Schema ($id, $ref), and other special JSON keys
|
|
65
|
+
|
|
66
|
+
- **Method Redefinition Warning**: Fixed "method redefined" warning for `:property` keyword (#153)
|
|
67
|
+
- Removed `:property` from `KEYWORDS` constant since it has dedicated implementation
|
|
68
|
+
|
|
69
|
+
### Internal
|
|
70
|
+
|
|
71
|
+
- **Type Introspection Improvements**: Enhanced type checking capabilities (#156)
|
|
72
|
+
- New helper methods: `array_type?()`, `boolean_union_type?()`, extracted `boolean_type?()`
|
|
73
|
+
- Improved encapsulation and testability
|
|
74
|
+
|
|
75
|
+
- **ValidationContext Decoupling**: Refactored validation adapter internals (#150)
|
|
76
|
+
- New plain data class `ValidationContext` for pre-computed validation values
|
|
77
|
+
- Replaces `__send__` usage with direct value passing
|
|
78
|
+
- Improved encapsulation and testability
|
|
79
|
+
|
|
80
|
+
- **Code Coverage Integration**: Added SimpleCov and Codecov for test coverage tracking
|
|
81
|
+
- Local HTML reports via SimpleCov
|
|
82
|
+
- CI badge reporting via Codecov
|
|
83
|
+
- Coverage uploads on Ruby 3.4.7 builds only
|
|
84
|
+
|
|
85
|
+
- **Test Infrastructure**: Comprehensive test expansion (~1800 lines of new tests)
|
|
86
|
+
- New test files: `external_ref_spec.rb`, `additional_properties_schema_spec.rb`, `tuple_validation_spec.rb`, `json_schema_equality_spec.rb`
|
|
87
|
+
- Enhanced builder test coverage
|
|
88
|
+
- Improved JSON Schema compliance testing
|
|
89
|
+
|
|
90
|
+
## [3.2.0] - 2025-12-28
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **Pluggable Validation Adapter System**: Complete overhaul of the validation layer to make it a distinct, pluggable component (#89)
|
|
95
|
+
- New `EasyTalk::ValidationAdapters::Base` abstract class defining the adapter interface
|
|
96
|
+
- New `EasyTalk::ValidationAdapters::Registry` for adapter registration and lookup
|
|
97
|
+
- New `EasyTalk::ValidationAdapters::ActiveModelAdapter` as the default adapter
|
|
98
|
+
- New `EasyTalk::ValidationAdapters::NoneAdapter` for schema-only use cases
|
|
99
|
+
- Per-model validation configuration: `define_schema(validations: false)`, `define_schema(validations: :none)`, or `define_schema(validations: CustomAdapter)`
|
|
100
|
+
- Per-property validation control with `validate: false` constraint
|
|
101
|
+
- Global configuration via `config.validation_adapter = :active_model`
|
|
102
|
+
|
|
103
|
+
- **Schema-Only Module**: New `EasyTalk::Schema` module for schema generation without ActiveModel (#89)
|
|
104
|
+
- Does not include `ActiveModel::API` or `ActiveModel::Validations`
|
|
105
|
+
- Ideal for API documentation, OpenAPI specs, and schema-first design
|
|
106
|
+
|
|
107
|
+
- **Pluggable Type Registry**: Runtime registration of custom types with their corresponding schema builders (#80)
|
|
108
|
+
- New `EasyTalk::Builders::Registry` class with `register`, `resolve`, `registered?`, `unregister`, `registered_types`, and `reset!` methods
|
|
109
|
+
- Added `EasyTalk.register_type` convenience method at module level
|
|
110
|
+
- Added `config.register_type` for configuration block registration
|
|
111
|
+
- Allows extending EasyTalk with custom types (e.g., Money, GeoPoint) without modifying gem source
|
|
112
|
+
|
|
113
|
+
- **Robust Type Introspection**: New `TypeIntrospection` module replacing brittle string-based type detection (#83)
|
|
114
|
+
- Predicate methods: `boolean_type?`, `typed_array?`, `nilable_type?`, `primitive_type?`
|
|
115
|
+
- Helper methods: `json_schema_type`, `get_type_class`, `extract_inner_type`
|
|
116
|
+
- Uses Sorbet's type system properly instead of string pattern matching
|
|
117
|
+
|
|
118
|
+
- **Standardized Validation Error Output**: Helper methods for API-friendly error formats (#88)
|
|
119
|
+
- **Flat format**: Simple array of field/message/code objects
|
|
120
|
+
- **JSON Pointer (RFC 6901)**: Paths like `/properties/name`
|
|
121
|
+
- **RFC 7807**: Problem Details for HTTP APIs
|
|
122
|
+
- **JSON:API**: Standard JSON:API error format
|
|
123
|
+
- Instance methods: `validation_errors(format:)`, `validation_errors_flat`, `validation_errors_json_pointer`, `validation_errors_rfc7807`, `validation_errors_jsonapi`
|
|
124
|
+
- Configuration options: `default_error_format`, `error_type_base_uri`, `include_error_codes`
|
|
125
|
+
|
|
126
|
+
- **Naming Strategies**: Support for automatic property name transformation (#61)
|
|
127
|
+
- Built-in strategies: `CAMEL_CASE`, `SNAKE_CASE`
|
|
128
|
+
- Optional `as:` property constraint for per-property name override
|
|
129
|
+
- Per-schema configuration: `define_schema { naming_strategy :camel_case }`
|
|
130
|
+
- Global configuration: `config.naming_strategy = :camel_case`
|
|
131
|
+
|
|
132
|
+
- **Array Composition Support**: `T::AnyOf`, `T::OneOf`, and `T::AllOf` now work with `T::Array` (#63)
|
|
133
|
+
- Example: `property :items, T::Array[T::OneOf[ProductA, ProductB]]`
|
|
134
|
+
|
|
135
|
+
- **Nested Model Validation in Arrays**: Arrays of EasyTalk::Model objects are now recursively validated (#112)
|
|
136
|
+
- Hash items in arrays are auto-instantiated to model instances
|
|
137
|
+
- Errors from nested models are merged with indexed paths (e.g., `addresses[0].street`)
|
|
138
|
+
|
|
139
|
+
### Changed
|
|
140
|
+
|
|
141
|
+
- **Deprecated `EasyTalk::ValidationBuilder`**: Use `EasyTalk::ValidationAdapters::ActiveModelAdapter` instead (deprecation warning shown on first use)
|
|
142
|
+
|
|
143
|
+
### Fixed
|
|
144
|
+
|
|
145
|
+
- **Default Value Assignment**: Default values are now properly assigned during initialization (#72)
|
|
146
|
+
- **Explicit Nil Preservation**: Explicitly passed `nil` values are preserved instead of being replaced with defaults (#79)
|
|
147
|
+
- **Optional Enum Validation**: Allow `nil` for optional properties with enum constraints (#64)
|
|
148
|
+
- **Optional Pattern Validation**: Allow `nil` for optional properties with pattern validation (#65)
|
|
149
|
+
- **Optional Format Validation**: Allow `nil` for optional properties with format validation (email, uri, uuid, etc.) (#75)
|
|
150
|
+
- **Optional Length Validation**: Allow `nil` for optional properties with length constraints (#76)
|
|
151
|
+
- **Schema Definition Mutation**: Avoid mutating schema definition during property building (#95)
|
|
152
|
+
- **Unknown Property Types**: Fail fast with `UnknownPropertyTypeError` instead of silently returning 'object' (#97)
|
|
153
|
+
- **respond_to_missing?**: Fixed `respond_to_missing?` implementation for additional properties (#98)
|
|
154
|
+
- **VALID_OPTIONS Mutation**: Avoid mutating `VALID_OPTIONS` constant in TypedArrayBuilder (#99)
|
|
155
|
+
- **Registry Reset**: `ValidationAdapters::Registry.reset!` now repopulates defaults (#100)
|
|
156
|
+
- **FunctionBuilder Error**: Replace deprecated Instructor error with `EasyTalk::UnsupportedTypeError` (#96)
|
|
157
|
+
- **Missing snake_case Strategy**: Added `SNAKE_CASE` constant to NamingStrategies module (#77)
|
|
158
|
+
|
|
159
|
+
### Internal
|
|
160
|
+
|
|
161
|
+
- Extracted shared schema methods into `SchemaMethods` mixin for code reuse between `Model` and `Schema` modules (#103)
|
|
162
|
+
- Centralized built-in type registration in `Builders::Registry` (#102)
|
|
163
|
+
- Added json_schemer for systematic validation testing with custom RSpec matchers
|
|
164
|
+
|
|
1
165
|
## [3.1.0] - 2025-12-18
|
|
2
166
|
|
|
3
167
|
### Added
|