easy_talk 3.0.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.yardopts +13 -0
  4. data/CHANGELOG.md +105 -0
  5. data/README.md +1268 -40
  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 +119 -10
  18. data/lib/easy_talk/builders/registry.rb +168 -0
  19. data/lib/easy_talk/builders/typed_array_builder.rb +20 -6
  20. data/lib/easy_talk/configuration.rb +51 -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/keywords.rb +2 -0
  32. data/lib/easy_talk/model.rb +125 -41
  33. data/lib/easy_talk/model_helper.rb +13 -0
  34. data/lib/easy_talk/naming_strategies.rb +20 -0
  35. data/lib/easy_talk/property.rb +32 -44
  36. data/lib/easy_talk/ref_helper.rb +27 -0
  37. data/lib/easy_talk/schema.rb +198 -0
  38. data/lib/easy_talk/schema_definition.rb +7 -1
  39. data/lib/easy_talk/schema_methods.rb +80 -0
  40. data/lib/easy_talk/tools/function_builder.rb +1 -1
  41. data/lib/easy_talk/type_introspection.rb +178 -0
  42. data/lib/easy_talk/types/base_composer.rb +2 -1
  43. data/lib/easy_talk/types/composer.rb +4 -0
  44. data/lib/easy_talk/validation_adapters/active_model_adapter.rb +329 -0
  45. data/lib/easy_talk/validation_adapters/base.rb +144 -0
  46. data/lib/easy_talk/validation_adapters/none_adapter.rb +36 -0
  47. data/lib/easy_talk/validation_adapters/registry.rb +87 -0
  48. data/lib/easy_talk/validation_builder.rb +28 -309
  49. data/lib/easy_talk/version.rb +1 -1
  50. data/lib/easy_talk.rb +41 -0
  51. metadata +28 -6
  52. data/docs/404.html +0 -25
  53. data/docs/_posts/2024-05-07-welcome-to-jekyll.markdown +0 -29
  54. data/easy_talk.gemspec +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce558538c73afc10d98c0c6b5e38e68ce033a79d1c212bb91fede27f10fb3523
4
- data.tar.gz: e46a7a67b6c1a3209108a800cefca8659381236c23ce14986e971babd874908d
3
+ metadata.gz: b77760f0bdffbb877509e133194733d397db6e5963b1484543791169db5dc840
4
+ data.tar.gz: 6e805469940229543c059952dc2311dd9acf7ea89ff45fde8b49b3e4d38dd85d
5
5
  SHA512:
6
- metadata.gz: b523e6cd50edc0594d98fffdb8a9de0616e5f58a2af435a23e5f4a81ac54b25692cd0bccba71c93eca812022efd298b2a9d654b34e3b8f37301ea8e7b16a4de3
7
- data.tar.gz: 7f287df819b0e09ddf5fce9506f045860dea876b0653cf7ede7dfb58e7a1d78e545933946921f0dfb4f1f02709357629f0b071c53e7c4ff945cdcf1908f5c2b6
6
+ metadata.gz: 5bf66646040995f9de8341e2a4e6ea63ae0c462a0f08f28779244e8eceff958e574042450a9a39cc2ef485e13d6c418e5f71296d6d8cc7e958339f432e84c572
7
+ data.tar.gz: 4c26c3bee7751682535f154efef1c4adb86cea08be6c6f09f9ebe08d6a2fde5604d71db884aa7f0de91787118f5bbb719028f8071ec4166ba69af7ad0d9b4ff1
data/.rubocop.yml CHANGED
@@ -114,3 +114,7 @@ Lint/DuplicateBranch:
114
114
 
115
115
  Gemspec/DevelopmentDependencies:
116
116
  Enabled: false
117
+
118
+ Naming/PredicateMethod:
119
+ Exclude:
120
+ - spec/support/schema_validation_matcher.rb
data/.yardopts ADDED
@@ -0,0 +1,13 @@
1
+ --readme README.md
2
+ --title "EasyTalk API Documentation"
3
+ --markup markdown
4
+ --output-dir docs/api
5
+ --protected
6
+ --no-private
7
+ --hide-void-return
8
+ --embed-mixins
9
+ lib/**/*.rb
10
+ -
11
+ README.md
12
+ CHANGELOG.md
13
+ CONSTRAINTS.md
data/CHANGELOG.md CHANGED
@@ -1,3 +1,108 @@
1
+ ## [3.2.0] - 2025-12-28
2
+
3
+ ### Added
4
+
5
+ - **Pluggable Validation Adapter System**: Complete overhaul of the validation layer to make it a distinct, pluggable component (#89)
6
+ - New `EasyTalk::ValidationAdapters::Base` abstract class defining the adapter interface
7
+ - New `EasyTalk::ValidationAdapters::Registry` for adapter registration and lookup
8
+ - New `EasyTalk::ValidationAdapters::ActiveModelAdapter` as the default adapter
9
+ - New `EasyTalk::ValidationAdapters::NoneAdapter` for schema-only use cases
10
+ - Per-model validation configuration: `define_schema(validations: false)`, `define_schema(validations: :none)`, or `define_schema(validations: CustomAdapter)`
11
+ - Per-property validation control with `validate: false` constraint
12
+ - Global configuration via `config.validation_adapter = :active_model`
13
+
14
+ - **Schema-Only Module**: New `EasyTalk::Schema` module for schema generation without ActiveModel (#89)
15
+ - Does not include `ActiveModel::API` or `ActiveModel::Validations`
16
+ - Ideal for API documentation, OpenAPI specs, and schema-first design
17
+
18
+ - **Pluggable Type Registry**: Runtime registration of custom types with their corresponding schema builders (#80)
19
+ - New `EasyTalk::Builders::Registry` class with `register`, `resolve`, `registered?`, `unregister`, `registered_types`, and `reset!` methods
20
+ - Added `EasyTalk.register_type` convenience method at module level
21
+ - Added `config.register_type` for configuration block registration
22
+ - Allows extending EasyTalk with custom types (e.g., Money, GeoPoint) without modifying gem source
23
+
24
+ - **Robust Type Introspection**: New `TypeIntrospection` module replacing brittle string-based type detection (#83)
25
+ - Predicate methods: `boolean_type?`, `typed_array?`, `nilable_type?`, `primitive_type?`
26
+ - Helper methods: `json_schema_type`, `get_type_class`, `extract_inner_type`
27
+ - Uses Sorbet's type system properly instead of string pattern matching
28
+
29
+ - **Standardized Validation Error Output**: Helper methods for API-friendly error formats (#88)
30
+ - **Flat format**: Simple array of field/message/code objects
31
+ - **JSON Pointer (RFC 6901)**: Paths like `/properties/name`
32
+ - **RFC 7807**: Problem Details for HTTP APIs
33
+ - **JSON:API**: Standard JSON:API error format
34
+ - Instance methods: `validation_errors(format:)`, `validation_errors_flat`, `validation_errors_json_pointer`, `validation_errors_rfc7807`, `validation_errors_jsonapi`
35
+ - Configuration options: `default_error_format`, `error_type_base_uri`, `include_error_codes`
36
+
37
+ - **Naming Strategies**: Support for automatic property name transformation (#61)
38
+ - Built-in strategies: `CAMEL_CASE`, `SNAKE_CASE`
39
+ - Optional `as:` property constraint for per-property name override
40
+ - Per-schema configuration: `define_schema { naming_strategy :camel_case }`
41
+ - Global configuration: `config.naming_strategy = :camel_case`
42
+
43
+ - **Array Composition Support**: `T::AnyOf`, `T::OneOf`, and `T::AllOf` now work with `T::Array` (#63)
44
+ - Example: `property :items, T::Array[T::OneOf[ProductA, ProductB]]`
45
+
46
+ - **Nested Model Validation in Arrays**: Arrays of EasyTalk::Model objects are now recursively validated (#112)
47
+ - Hash items in arrays are auto-instantiated to model instances
48
+ - Errors from nested models are merged with indexed paths (e.g., `addresses[0].street`)
49
+
50
+ ### Changed
51
+
52
+ - **Deprecated `EasyTalk::ValidationBuilder`**: Use `EasyTalk::ValidationAdapters::ActiveModelAdapter` instead (deprecation warning shown on first use)
53
+
54
+ ### Fixed
55
+
56
+ - **Default Value Assignment**: Default values are now properly assigned during initialization (#72)
57
+ - **Explicit Nil Preservation**: Explicitly passed `nil` values are preserved instead of being replaced with defaults (#79)
58
+ - **Optional Enum Validation**: Allow `nil` for optional properties with enum constraints (#64)
59
+ - **Optional Pattern Validation**: Allow `nil` for optional properties with pattern validation (#65)
60
+ - **Optional Format Validation**: Allow `nil` for optional properties with format validation (email, uri, uuid, etc.) (#75)
61
+ - **Optional Length Validation**: Allow `nil` for optional properties with length constraints (#76)
62
+ - **Schema Definition Mutation**: Avoid mutating schema definition during property building (#95)
63
+ - **Unknown Property Types**: Fail fast with `UnknownPropertyTypeError` instead of silently returning 'object' (#97)
64
+ - **respond_to_missing?**: Fixed `respond_to_missing?` implementation for additional properties (#98)
65
+ - **VALID_OPTIONS Mutation**: Avoid mutating `VALID_OPTIONS` constant in TypedArrayBuilder (#99)
66
+ - **Registry Reset**: `ValidationAdapters::Registry.reset!` now repopulates defaults (#100)
67
+ - **FunctionBuilder Error**: Replace deprecated Instructor error with `EasyTalk::UnsupportedTypeError` (#96)
68
+ - **Missing snake_case Strategy**: Added `SNAKE_CASE` constant to NamingStrategies module (#77)
69
+
70
+ ### Internal
71
+
72
+ - Extracted shared schema methods into `SchemaMethods` mixin for code reuse between `Model` and `Schema` modules (#103)
73
+ - Centralized built-in type registration in `Builders::Registry` (#102)
74
+ - Added json_schemer for systematic validation testing with custom RSpec matchers
75
+
76
+ ## [3.1.0] - 2025-12-18
77
+
78
+ ### Added
79
+ - **JSON Schema `$schema` Keyword Support**: Added ability to declare which JSON Schema draft version schemas conform to
80
+ - New `schema_version` configuration option supporting Draft-04, Draft-06, Draft-07, Draft 2019-09, and Draft 2020-12
81
+ - Global configuration via `EasyTalk.configure { |c| c.schema_version = :draft202012 }`
82
+ - Per-model override using `schema_version` keyword in `define_schema` block
83
+ - Support for custom schema URIs
84
+ - `$schema` only appears at root level (not in nested models)
85
+ - Default is `:none` for backward compatibility
86
+
87
+ - **JSON Schema `$id` Keyword Support**: Added ability to provide a unique identifier URI for schemas
88
+ - New `schema_id` configuration option for setting schema identifiers
89
+ - Global configuration via `EasyTalk.configure { |c| c.schema_id = 'https://example.com/schema.json' }`
90
+ - Per-model override using `schema_id` keyword in `define_schema` block
91
+ - Supports absolute URIs, relative URIs, and URN formats
92
+ - `$id` only appears at root level (not in nested models)
93
+ - Default is `nil` for backward compatibility
94
+
95
+ - **JSON Schema `$ref` and `$defs` Support**: Added ability to reference reusable schema definitions for nested models
96
+ - New `use_refs` configuration option to globally enable `$ref` for nested EasyTalk models
97
+ - Global configuration via `EasyTalk.configure { |c| c.use_refs = true }`
98
+ - Per-property override using `ref: true` or `ref: false` constraint
99
+ - Nested models are automatically added to `$defs` when `$ref` is enabled
100
+ - Supports direct model properties, `T::Array[Model]`, and `T.nilable(Model)` types
101
+ - Nilable models with `$ref` use `anyOf` with `$ref` and `null` type
102
+ - Multiple references to the same model only create one `$defs` entry
103
+ - Additional constraints (title, description) can be combined with `$ref`
104
+ - Default is `false` for backward compatibility (nested schemas are inlined)
105
+
1
106
  ## [3.0.0] - 2025-01-03
2
107
 
3
108
  ### BREAKING CHANGES