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.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.yardopts +13 -0
- data/CHANGELOG.md +75 -0
- data/README.md +616 -35
- 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 +55 -0
- data/docs/nested-models.markdown +216 -0
- data/docs/property-types.markdown +212 -0
- data/docs/schema-definition.markdown +180 -0
- data/lib/easy_talk/builders/base_builder.rb +4 -2
- data/lib/easy_talk/builders/composition_builder.rb +10 -12
- data/lib/easy_talk/builders/object_builder.rb +45 -30
- data/lib/easy_talk/builders/registry.rb +168 -0
- data/lib/easy_talk/builders/typed_array_builder.rb +15 -4
- data/lib/easy_talk/configuration.rb +31 -1
- 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 +2 -0
- data/lib/easy_talk/errors_helper.rb +63 -34
- data/lib/easy_talk/model.rb +123 -90
- data/lib/easy_talk/model_helper.rb +13 -0
- data/lib/easy_talk/naming_strategies.rb +20 -0
- data/lib/easy_talk/property.rb +16 -94
- data/lib/easy_talk/ref_helper.rb +27 -0
- data/lib/easy_talk/schema.rb +198 -0
- data/lib/easy_talk/schema_definition.rb +7 -1
- data/lib/easy_talk/schema_methods.rb +80 -0
- data/lib/easy_talk/tools/function_builder.rb +1 -1
- data/lib/easy_talk/type_introspection.rb +178 -0
- data/lib/easy_talk/types/base_composer.rb +2 -1
- data/lib/easy_talk/types/composer.rb +4 -0
- data/lib/easy_talk/validation_adapters/active_model_adapter.rb +329 -0
- data/lib/easy_talk/validation_adapters/base.rb +144 -0
- data/lib/easy_talk/validation_adapters/none_adapter.rb +36 -0
- data/lib/easy_talk/validation_adapters/registry.rb +87 -0
- data/lib/easy_talk/validation_builder.rb +28 -309
- data/lib/easy_talk/version.rb +1 -1
- data/lib/easy_talk.rb +41 -0
- metadata +26 -4
- data/docs/404.html +0 -25
- data/docs/_posts/2024-05-07-welcome-to-jekyll.markdown +0 -29
- data/easy_talk.gemspec +0 -39
data/README.md
CHANGED
|
@@ -2,23 +2,179 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/easy_talk)
|
|
4
4
|
[](https://github.com/sergiobayona/easy_talk/actions/workflows/dev-build.yml)
|
|
5
|
+
[](https://rubydoc.info/gems/easy_talk)
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Introduction](#introduction)
|
|
10
|
+
- [What is EasyTalk?](#what-is-easytalk)
|
|
11
|
+
- [Key Features](#key-features)
|
|
12
|
+
- [Use Cases](#use-cases)
|
|
13
|
+
- [Inspiration](#inspiration)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Requirements](#requirements)
|
|
16
|
+
- [Version 2.0.0 Breaking Changes](#version-200-breaking-changes)
|
|
17
|
+
- [Installation Steps](#installation-steps)
|
|
18
|
+
- [Verification](#verification)
|
|
19
|
+
- [Quick Start](#quick-start)
|
|
20
|
+
- [Minimal Example](#minimal-example)
|
|
21
|
+
- [Generated JSON Schema](#generated-json-schema)
|
|
22
|
+
- [Basic Usage](#basic-usage)
|
|
23
|
+
- [Core Concepts](#core-concepts)
|
|
24
|
+
- [Schema Definition](#schema-definition)
|
|
25
|
+
- [Property Types](#property-types)
|
|
26
|
+
- [Ruby Types](#ruby-types)
|
|
27
|
+
- [Sorbet-Style Types](#sorbet-style-types)
|
|
28
|
+
- [Custom Types](#custom-types)
|
|
29
|
+
- [Property Constraints](#property-constraints)
|
|
30
|
+
- [Required vs Optional Properties](#required-vs-optional-properties)
|
|
31
|
+
- [Automatic Validation Generation](#automatic-validation-generation)
|
|
32
|
+
- [Manual Validation Overrides](#manual-validation-overrides)
|
|
33
|
+
- [Defining Schemas](#defining-schemas)
|
|
34
|
+
- [Basic Schema Structure](#basic-schema-structure)
|
|
35
|
+
- [Property Definitions](#property-definitions)
|
|
36
|
+
- [Arrays and Collections](#arrays-and-collections)
|
|
37
|
+
- [Constraints and Automatic Validations](#constraints-and-automatic-validations)
|
|
38
|
+
- [Supported Constraint-to-Validation Mappings](#supported-constraint-to-validation-mappings)
|
|
39
|
+
- [Additional Properties](#additional-properties)
|
|
40
|
+
- [Property Naming](#property-naming)
|
|
41
|
+
- [Schema Composition](#schema-composition)
|
|
42
|
+
- [Using T::AnyOf](#using-tanyof)
|
|
43
|
+
- [Using T::OneOf](#using-toneof)
|
|
44
|
+
- [Using T::AllOf](#using-tallof)
|
|
45
|
+
- [Array Composition](#array-composition)
|
|
46
|
+
- [Complex Compositions](#complex-compositions)
|
|
47
|
+
- [Reusing Models](#reusing-models)
|
|
48
|
+
- [ActiveModel Integration](#activemodel-integration)
|
|
49
|
+
- [Enhanced Validation System](#enhanced-validation-system)
|
|
50
|
+
- [Error Handling](#error-handling)
|
|
51
|
+
- [Standardized Error Formatting](#standardized-error-formatting)
|
|
52
|
+
- [Available Formats](#available-formats)
|
|
53
|
+
- [Instance Methods](#instance-methods)
|
|
54
|
+
- [Direct API Usage](#direct-api-usage)
|
|
55
|
+
- [Configuration](#configuration)
|
|
56
|
+
- [Model Attributes](#model-attributes)
|
|
57
|
+
- [Advanced Features](#advanced-features)
|
|
58
|
+
- [Schema-Only Mode (EasyTalk::Schema)](#schema-only-mode-easytalkschema)
|
|
59
|
+
- [Key Differences from EasyTalk::Model](#key-differences-from-easytalkmodel)
|
|
60
|
+
- [When to Use Each](#when-to-use-each)
|
|
61
|
+
- [LLM Function Generation](#llm-function-generation)
|
|
62
|
+
- [Schema Transformation](#schema-transformation)
|
|
63
|
+
- [Type Checking and Validation](#type-checking-and-validation)
|
|
64
|
+
- [Custom Type Builders](#custom-type-builders)
|
|
65
|
+
- [Registering Custom Types](#registering-custom-types)
|
|
66
|
+
- [Creating a Custom Builder](#creating-a-custom-builder)
|
|
67
|
+
- [Collection Type Builders](#collection-type-builders)
|
|
68
|
+
- [Overriding Built-in Types](#overriding-built-in-types)
|
|
69
|
+
- [Registry API](#registry-api)
|
|
70
|
+
- [Type Introspection](#type-introspection)
|
|
71
|
+
- [Configuration](#configuration-1)
|
|
72
|
+
- [Global Settings](#global-settings)
|
|
73
|
+
- [Automatic Validation Configuration](#automatic-validation-configuration)
|
|
74
|
+
- [Per-Model Configuration](#per-model-configuration)
|
|
75
|
+
- [Validation Adapters](#validation-adapters)
|
|
76
|
+
- [Built-in Adapters](#built-in-adapters)
|
|
77
|
+
- [Global Adapter Configuration](#global-adapter-configuration)
|
|
78
|
+
- [Per-Model Validation Control](#per-model-validation-control)
|
|
79
|
+
- [Per-Property Validation Control](#per-property-validation-control)
|
|
80
|
+
- [Custom Validation Adapters](#custom-validation-adapters)
|
|
81
|
+
- [Examples](#examples)
|
|
82
|
+
- [User Registration (with Auto-Validations)](#user-registration-with-auto-validations)
|
|
83
|
+
- [Payment Processing](#payment-processing)
|
|
84
|
+
- [Complex Object Hierarchies](#complex-object-hierarchies)
|
|
85
|
+
- [API Integration](#api-integration)
|
|
86
|
+
- [Troubleshooting](#troubleshooting)
|
|
87
|
+
- [Common Errors](#common-errors)
|
|
88
|
+
- ["Invalid property name"](#invalid-property-name)
|
|
89
|
+
- ["Property type is missing"](#property-type-is-missing)
|
|
90
|
+
- ["Unknown option"](#unknown-option)
|
|
91
|
+
- [Schema Validation Issues](#schema-validation-issues)
|
|
92
|
+
- [Type Errors](#type-errors)
|
|
93
|
+
- [Best Practices](#best-practices)
|
|
94
|
+
- [Nullable vs Optional Properties in EasyTalk](#nullable-vs-optional-properties-in-easytalk)
|
|
95
|
+
- [Key Concepts](#key-concepts)
|
|
96
|
+
- [Nullable Properties](#nullable-properties)
|
|
97
|
+
- [Optional Properties](#optional-properties)
|
|
98
|
+
- [Nullable AND Optional Properties](#nullable-and-optional-properties)
|
|
99
|
+
- [Configuration Options](#configuration-options)
|
|
100
|
+
- [Practical Examples](#practical-examples)
|
|
101
|
+
- [User Profile Schema](#user-profile-schema)
|
|
102
|
+
- [Common Gotchas](#common-gotchas)
|
|
103
|
+
- [Misconception: Nullable Implies Optional](#misconception-nullable-implies-optional)
|
|
104
|
+
- [Misconception: Optional Properties Accept Null](#misconception-optional-properties-accept-null)
|
|
105
|
+
- [Migration from Earlier Versions](#migration-from-earlier-versions)
|
|
106
|
+
- [Best Practices](#best-practices-1)
|
|
107
|
+
- [JSON Schema Comparison](#json-schema-comparison)
|
|
108
|
+
- [Migration Guide from v1.x to v2.0](#migration-guide-from-v1x-to-v20)
|
|
109
|
+
- [Breaking Changes Summary](#breaking-changes-summary)
|
|
110
|
+
- [Migration Steps](#migration-steps)
|
|
111
|
+
- [1. Replace Hash-based Nested Schemas](#1-replace-hash-based-nested-schemas)
|
|
112
|
+
- [2. Review Automatic Validations](#2-review-automatic-validations)
|
|
113
|
+
- [3. Configuration Updates](#3-configuration-updates)
|
|
114
|
+
- [Compatibility Notes](#compatibility-notes)
|
|
115
|
+
- [Development and Contributing](#development-and-contributing)
|
|
116
|
+
- [Setting Up the Development Environment](#setting-up-the-development-environment)
|
|
117
|
+
- [Running Tests](#running-tests)
|
|
118
|
+
- [Code Quality](#code-quality)
|
|
119
|
+
- [Contributing Guidelines](#contributing-guidelines)
|
|
120
|
+
- [JSON Schema Version (`$schema` Keyword)](#json-schema-version-schema-keyword)
|
|
121
|
+
- [Why Use `$schema`?](#why-use-schema)
|
|
122
|
+
- [Supported Draft Versions](#supported-draft-versions)
|
|
123
|
+
- [Global Configuration](#global-configuration)
|
|
124
|
+
- [Per-Model Configuration](#per-model-configuration-1)
|
|
125
|
+
- [Disabling `$schema` for Specific Models](#disabling-schema-for-specific-models)
|
|
126
|
+
- [Custom Schema URIs](#custom-schema-uris)
|
|
127
|
+
- [Nested Models](#nested-models)
|
|
128
|
+
- [Default Behavior](#default-behavior)
|
|
129
|
+
- [Best Practices](#best-practices-2)
|
|
130
|
+
- [Schema Identifier (`$id` Keyword)](#schema-identifier-id-keyword)
|
|
131
|
+
- [Why Use `$id`?](#why-use-id)
|
|
132
|
+
- [Global Configuration](#global-configuration-1)
|
|
133
|
+
- [Per-Model Configuration](#per-model-configuration-2)
|
|
134
|
+
- [Disabling `$id` for Specific Models](#disabling-id-for-specific-models)
|
|
135
|
+
- [Combining `$schema` and `$id`](#combining-schema-and-id)
|
|
136
|
+
- [Nested Models](#nested-models-1)
|
|
137
|
+
- [URI Formats](#uri-formats)
|
|
138
|
+
- [Default Behavior](#default-behavior-1)
|
|
139
|
+
- [Best Practices](#best-practices-3)
|
|
140
|
+
- [Schema References (`$ref` and `$defs`)](#schema-references-ref-and-defs)
|
|
141
|
+
- [Why Use `$ref`?](#why-use-ref)
|
|
142
|
+
- [Default Behavior (Inline Schemas)](#default-behavior-inline-schemas)
|
|
143
|
+
- [Enabling `$ref` References](#enabling-ref-references)
|
|
144
|
+
- [Global Configuration](#global-configuration-2)
|
|
145
|
+
- [Per-Property Configuration](#per-property-configuration)
|
|
146
|
+
- [Arrays of Models](#arrays-of-models)
|
|
147
|
+
- [Nilable Models with `$ref`](#nilable-models-with-ref)
|
|
148
|
+
- [Multiple References to the Same Model](#multiple-references-to-the-same-model)
|
|
149
|
+
- [Combining `$ref` with Other Constraints](#combining-ref-with-other-constraints)
|
|
150
|
+
- [Interaction with `compose`](#interaction-with-compose)
|
|
151
|
+
- [Best Practices](#best-practices-4)
|
|
152
|
+
- [Default Behavior](#default-behavior-2)
|
|
153
|
+
- [JSON Schema Compatibility](#json-schema-compatibility)
|
|
154
|
+
- [Supported Versions](#supported-versions)
|
|
155
|
+
- [Specification Compliance](#specification-compliance)
|
|
156
|
+
- [Known Limitations](#known-limitations)
|
|
157
|
+
- [API Reference](#api-reference)
|
|
158
|
+
- [Core Modules](#core-modules)
|
|
159
|
+
- [Builders](#builders)
|
|
160
|
+
- [Configuration & Utilities](#configuration--utilities)
|
|
161
|
+
- [License](#license)
|
|
5
162
|
|
|
6
163
|
## Introduction
|
|
7
164
|
|
|
8
165
|
### What is EasyTalk?
|
|
9
|
-
EasyTalk is a Ruby library
|
|
166
|
+
EasyTalk is a Ruby library for defining structured data models with automatic JSON Schema generation and flexible validation. Define your schema once and get both a JSON Schema document and runtime validations from a single source of truth.
|
|
10
167
|
|
|
11
168
|
### Key Features
|
|
12
|
-
* **Intuitive Schema Definition**:
|
|
13
|
-
* **
|
|
14
|
-
* **
|
|
15
|
-
* **
|
|
16
|
-
* **
|
|
17
|
-
* **
|
|
18
|
-
* **
|
|
19
|
-
* **
|
|
20
|
-
* **Schema
|
|
21
|
-
* **Schema References**: Use `$ref` and `$defs` for reusable schema definitions, reducing duplication when models are used in multiple places.
|
|
169
|
+
* **Intuitive Schema Definition**: Define JSON Schema using Ruby classes with a clean, declarative DSL.
|
|
170
|
+
* **Rich Type System**: Supports Ruby primitives plus Sorbet-style types (`T::Array[Type]`, `T.nilable(Type)`, `T::Boolean`) and composition types (`T::AnyOf`, `T::OneOf`, `T::AllOf`).
|
|
171
|
+
* **Automatic Validations**: Schema constraints automatically generate ActiveModel validations, including nested model validation within arrays.
|
|
172
|
+
* **API Error Formatting**: Format validation errors in multiple standards (flat, JSON Pointer, RFC 7807, JSON:API).
|
|
173
|
+
* **LLM Function Support**: Generate JSON Schema for LLM function calling (OpenAI, Anthropic, etc.).
|
|
174
|
+
* **Schema Composition**: Reference models within other models and use `$ref`/`$defs` for reusable definitions.
|
|
175
|
+
* **Nested Model Instantiation**: Hash attributes automatically instantiate nested EasyTalk models, including within arrays.
|
|
176
|
+
* **Flexible Configuration**: Global and per-model settings for validation behavior, naming strategies, and schema output.
|
|
177
|
+
* **JSON Schema Versions**: Support for Draft-04 through Draft 2020-12 with configurable `$schema` and `$id` keywords.
|
|
22
178
|
|
|
23
179
|
### Use Cases
|
|
24
180
|
- API request/response validation
|
|
@@ -28,7 +184,7 @@ EasyTalk is a Ruby library that simplifies defining and generating JSON Schema.
|
|
|
28
184
|
- Configuration schema definitions
|
|
29
185
|
|
|
30
186
|
### Inspiration
|
|
31
|
-
Inspired by Python's Pydantic library, EasyTalk brings similar functionality to the Ruby ecosystem, providing a Ruby-friendly approach to JSON Schema operations.
|
|
187
|
+
Inspired by Python's [Pydantic](https://docs.pydantic.dev/) library, EasyTalk brings similar functionality to the Ruby ecosystem, providing a Ruby-friendly approach to JSON Schema operations.
|
|
32
188
|
|
|
33
189
|
## Installation
|
|
34
190
|
|
|
@@ -367,6 +523,27 @@ company.location = "New York" # Additional property
|
|
|
367
523
|
company.employee_count = 100 # Additional property
|
|
368
524
|
```
|
|
369
525
|
|
|
526
|
+
### Property Naming
|
|
527
|
+
You can configure the naming strategy for properties globally or per schema:
|
|
528
|
+
|
|
529
|
+
```ruby
|
|
530
|
+
EasyTalk.configure do |config|
|
|
531
|
+
config.property_naming_strategy = :snake_case # Options: :identity, :snake_case, :camel_case, :pascal_case
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
define_schema do
|
|
535
|
+
property_naming_strategy :camel_case # Overrides global setting for this schema
|
|
536
|
+
property :name, String
|
|
537
|
+
end
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
This affects how property names are represented in the generated JSON Schema.
|
|
541
|
+
Additionally, names can be overridden per property:
|
|
542
|
+
|
|
543
|
+
```ruby
|
|
544
|
+
property :first_name, String, as: "firstName" # Overrides global naming strategy
|
|
545
|
+
```
|
|
546
|
+
|
|
370
547
|
## Schema Composition
|
|
371
548
|
|
|
372
549
|
### Using T::AnyOf
|
|
@@ -408,13 +585,67 @@ class VehicleRegistration
|
|
|
408
585
|
end
|
|
409
586
|
```
|
|
410
587
|
|
|
588
|
+
### Array Composition
|
|
589
|
+
Composition types can be combined with arrays to define collections where each item must match one of several schemas:
|
|
590
|
+
|
|
591
|
+
```ruby
|
|
592
|
+
class ProductA
|
|
593
|
+
include EasyTalk::Model
|
|
594
|
+
define_schema do
|
|
595
|
+
property :sku, String
|
|
596
|
+
property :weight, Float
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
class ProductB
|
|
601
|
+
include EasyTalk::Model
|
|
602
|
+
define_schema do
|
|
603
|
+
property :sku, String
|
|
604
|
+
property :digital_url, String
|
|
605
|
+
end
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
class Order
|
|
609
|
+
include EasyTalk::Model
|
|
610
|
+
|
|
611
|
+
define_schema do
|
|
612
|
+
property :order_id, String
|
|
613
|
+
# Each item in the array must match exactly one of the product schemas
|
|
614
|
+
property :items, T::Array[T::OneOf[ProductA, ProductB]]
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
This generates a JSON Schema where the `items` array validates each element against `oneOf`:
|
|
620
|
+
|
|
621
|
+
```json
|
|
622
|
+
{
|
|
623
|
+
"properties": {
|
|
624
|
+
"items": {
|
|
625
|
+
"type": "array",
|
|
626
|
+
"items": {
|
|
627
|
+
"oneOf": [
|
|
628
|
+
{ "type": "object", "properties": { "sku": {...}, "weight": {...} }, ... },
|
|
629
|
+
{ "type": "object", "properties": { "sku": {...}, "digital_url": {...} }, ... }
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
You can use any composition type with arrays:
|
|
638
|
+
- `T::Array[T::OneOf[A, B]]` - each item matches exactly one schema
|
|
639
|
+
- `T::Array[T::AnyOf[A, B]]` - each item matches one or more schemas
|
|
640
|
+
- `T::Array[T::AllOf[A, B]]` - each item matches all schemas
|
|
641
|
+
|
|
411
642
|
### Complex Compositions
|
|
412
643
|
You can combine composition types to create complex schemas:
|
|
413
644
|
|
|
414
645
|
```ruby
|
|
415
646
|
class ComplexObject
|
|
416
647
|
include EasyTalk::Model
|
|
417
|
-
|
|
648
|
+
|
|
418
649
|
define_schema do
|
|
419
650
|
property :basic_info, BaseInfo
|
|
420
651
|
property :specific_details, T::OneOf[DetailTypeA, DetailTypeB]
|
|
@@ -480,6 +711,78 @@ user.errors[:age] # => ["must be greater than 21"] # Custom validation
|
|
|
480
711
|
user.errors[:height] # => ["must be greater than 0"] # Overridden validation
|
|
481
712
|
```
|
|
482
713
|
|
|
714
|
+
### Standardized Error Formatting
|
|
715
|
+
|
|
716
|
+
EasyTalk provides multiple output formats for validation errors, making it easy to build consistent API responses.
|
|
717
|
+
|
|
718
|
+
#### Available Formats
|
|
719
|
+
|
|
720
|
+
| Format | Description | Use Case |
|
|
721
|
+
|--------|-------------|----------|
|
|
722
|
+
| `:flat` | Simple array of field/message/code objects | General purpose APIs |
|
|
723
|
+
| `:json_pointer` | Array with JSON Pointer (RFC 6901) paths | JSON Schema validation |
|
|
724
|
+
| `:rfc7807` | RFC 7807 Problem Details format | Standards-compliant APIs |
|
|
725
|
+
| `:jsonapi` | JSON:API specification error format | JSON:API implementations |
|
|
726
|
+
|
|
727
|
+
#### Instance Methods
|
|
728
|
+
|
|
729
|
+
Every EasyTalk model includes convenient methods for error formatting:
|
|
730
|
+
|
|
731
|
+
```ruby
|
|
732
|
+
user = User.new(name: "", email: "invalid")
|
|
733
|
+
user.valid?
|
|
734
|
+
|
|
735
|
+
# Use default format (configurable globally)
|
|
736
|
+
user.validation_errors
|
|
737
|
+
# => [{"field" => "name", "message" => "can't be blank", "code" => "blank"}, ...]
|
|
738
|
+
|
|
739
|
+
# Flat format
|
|
740
|
+
user.validation_errors_flat
|
|
741
|
+
# => [{"field" => "name", "message" => "can't be blank", "code" => "blank"}]
|
|
742
|
+
|
|
743
|
+
# JSON Pointer format
|
|
744
|
+
user.validation_errors_json_pointer
|
|
745
|
+
# => [{"pointer" => "/properties/name", "message" => "can't be blank", "code" => "blank"}]
|
|
746
|
+
|
|
747
|
+
# RFC 7807 Problem Details
|
|
748
|
+
user.validation_errors_rfc7807
|
|
749
|
+
# => {
|
|
750
|
+
# "type" => "about:blank#validation-error",
|
|
751
|
+
# "title" => "Validation Failed",
|
|
752
|
+
# "status" => 422,
|
|
753
|
+
# "detail" => "The request contains invalid parameters",
|
|
754
|
+
# "errors" => [...]
|
|
755
|
+
# }
|
|
756
|
+
|
|
757
|
+
# JSON:API format
|
|
758
|
+
user.validation_errors_jsonapi
|
|
759
|
+
# => {
|
|
760
|
+
# "errors" => [
|
|
761
|
+
# {"status" => "422", "source" => {"pointer" => "/data/attributes/name"}, ...}
|
|
762
|
+
# ]
|
|
763
|
+
# }
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
#### Direct API Usage
|
|
767
|
+
|
|
768
|
+
You can also format errors directly using the `ErrorFormatter` module:
|
|
769
|
+
|
|
770
|
+
```ruby
|
|
771
|
+
EasyTalk::ErrorFormatter.format(user.errors, format: :rfc7807, title: "User Validation Failed")
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
#### Configuration
|
|
775
|
+
|
|
776
|
+
Configure error formatting globally:
|
|
777
|
+
|
|
778
|
+
```ruby
|
|
779
|
+
EasyTalk.configure do |config|
|
|
780
|
+
config.default_error_format = :rfc7807 # Default format for validation_errors
|
|
781
|
+
config.error_type_base_uri = 'https://api.example.com/errors' # Base URI for RFC 7807
|
|
782
|
+
config.include_error_codes = true # Include error codes in output
|
|
783
|
+
end
|
|
784
|
+
```
|
|
785
|
+
|
|
483
786
|
### Model Attributes
|
|
484
787
|
EasyTalk models provide getters and setters for all defined properties:
|
|
485
788
|
|
|
@@ -523,6 +826,57 @@ user.address.street # => "123 Main St"
|
|
|
523
826
|
|
|
524
827
|
## Advanced Features
|
|
525
828
|
|
|
829
|
+
### Schema-Only Mode (EasyTalk::Schema)
|
|
830
|
+
|
|
831
|
+
For scenarios where you need JSON Schema generation without ActiveModel validations, use `EasyTalk::Schema` instead of `EasyTalk::Model`. This is ideal for:
|
|
832
|
+
|
|
833
|
+
- API documentation and OpenAPI spec generation
|
|
834
|
+
- Schema-first design where validation happens elsewhere
|
|
835
|
+
- High-performance scenarios where validation overhead is unwanted
|
|
836
|
+
- Generating schemas for external systems
|
|
837
|
+
|
|
838
|
+
```ruby
|
|
839
|
+
class ApiContract
|
|
840
|
+
include EasyTalk::Schema # Not EasyTalk::Model
|
|
841
|
+
|
|
842
|
+
define_schema do
|
|
843
|
+
title 'API Contract'
|
|
844
|
+
description 'A schema-only contract'
|
|
845
|
+
property :name, String, min_length: 2
|
|
846
|
+
property :age, Integer, minimum: 0
|
|
847
|
+
end
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
# Schema generation works the same
|
|
851
|
+
ApiContract.json_schema
|
|
852
|
+
# => {"type" => "object", "title" => "API Contract", ...}
|
|
853
|
+
|
|
854
|
+
# Instances can be created and accessed
|
|
855
|
+
contract = ApiContract.new(name: 'Test', age: 25)
|
|
856
|
+
contract.name # => 'Test'
|
|
857
|
+
|
|
858
|
+
# But no validation methods are available
|
|
859
|
+
contract.valid? # => NoMethodError
|
|
860
|
+
contract.errors # => NoMethodError
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
#### Key Differences from EasyTalk::Model
|
|
864
|
+
|
|
865
|
+
| Feature | EasyTalk::Model | EasyTalk::Schema |
|
|
866
|
+
|---------|-----------------|------------------|
|
|
867
|
+
| JSON Schema generation | Yes | Yes |
|
|
868
|
+
| Property accessors | Yes | Yes |
|
|
869
|
+
| Nested model instantiation | Yes | Yes |
|
|
870
|
+
| ActiveModel::Validations | Yes | No |
|
|
871
|
+
| `valid?` / `errors` | Yes | No |
|
|
872
|
+
| Validation adapters | Yes | N/A |
|
|
873
|
+
| Error formatting | Yes | No |
|
|
874
|
+
|
|
875
|
+
#### When to Use Each
|
|
876
|
+
|
|
877
|
+
- **Use `EasyTalk::Model`** when you need runtime validation of data (form inputs, API requests, user data)
|
|
878
|
+
- **Use `EasyTalk::Schema`** when you only need the schema definition (documentation, code generation, external validation)
|
|
879
|
+
|
|
526
880
|
### LLM Function Generation
|
|
527
881
|
EasyTalk provides a helper method for generating OpenAI function specifications:
|
|
528
882
|
|
|
@@ -569,16 +923,125 @@ property :age, Integer, enum: ["young", "old"] # Error!
|
|
|
569
923
|
```
|
|
570
924
|
|
|
571
925
|
### Custom Type Builders
|
|
572
|
-
|
|
926
|
+
|
|
927
|
+
EasyTalk provides a type registry that allows you to register custom types with their corresponding schema builders.
|
|
928
|
+
|
|
929
|
+
#### Registering Custom Types
|
|
930
|
+
|
|
931
|
+
Register types in your configuration:
|
|
573
932
|
|
|
574
933
|
```ruby
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
934
|
+
EasyTalk.configure do |config|
|
|
935
|
+
config.register_type(Money, MoneySchemaBuilder)
|
|
936
|
+
end
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
Or register directly with the registry:
|
|
940
|
+
|
|
941
|
+
```ruby
|
|
942
|
+
EasyTalk::Builders::Registry.register(Money, MoneySchemaBuilder)
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
#### Creating a Custom Builder
|
|
946
|
+
|
|
947
|
+
Custom builders extend `BaseBuilder` and implement the schema generation logic:
|
|
948
|
+
|
|
949
|
+
```ruby
|
|
950
|
+
class MoneySchemaBuilder < EasyTalk::Builders::BaseBuilder
|
|
951
|
+
VALID_OPTIONS = {
|
|
952
|
+
currency: { type: T.nilable(String), key: :currency }
|
|
953
|
+
}.freeze
|
|
954
|
+
|
|
955
|
+
def initialize(name, options = {})
|
|
956
|
+
super(name, { type: 'object' }, options, VALID_OPTIONS)
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
def build
|
|
960
|
+
schema.merge(
|
|
961
|
+
properties: {
|
|
962
|
+
amount: { type: 'number' },
|
|
963
|
+
currency: { type: 'string', default: options[:currency] || 'USD' }
|
|
964
|
+
},
|
|
965
|
+
required: %w[amount currency]
|
|
966
|
+
)
|
|
967
|
+
end
|
|
968
|
+
end
|
|
969
|
+
|
|
970
|
+
# Register and use
|
|
971
|
+
EasyTalk::Builders::Registry.register(Money, MoneySchemaBuilder)
|
|
972
|
+
|
|
973
|
+
class Order
|
|
974
|
+
include EasyTalk::Model
|
|
975
|
+
|
|
976
|
+
define_schema do
|
|
977
|
+
property :total, Money, currency: 'EUR'
|
|
978
|
+
end
|
|
979
|
+
end
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
#### Collection Type Builders
|
|
983
|
+
|
|
984
|
+
For types that wrap other types (like arrays), use the `collection: true` option:
|
|
985
|
+
|
|
986
|
+
```ruby
|
|
987
|
+
EasyTalk::Builders::Registry.register(
|
|
988
|
+
CustomCollection,
|
|
989
|
+
CustomCollectionBuilder,
|
|
990
|
+
collection: true
|
|
991
|
+
)
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
Collection builders receive `(name, inner_type, constraints)` instead of `(name, constraints)`.
|
|
995
|
+
|
|
996
|
+
#### Overriding Built-in Types
|
|
997
|
+
|
|
998
|
+
You can override built-in type builders:
|
|
999
|
+
|
|
1000
|
+
```ruby
|
|
1001
|
+
class EnhancedStringBuilder < EasyTalk::Builders::StringBuilder
|
|
1002
|
+
def build
|
|
1003
|
+
result = super
|
|
1004
|
+
result[:custom_extension] = true
|
|
1005
|
+
result
|
|
580
1006
|
end
|
|
581
1007
|
end
|
|
1008
|
+
|
|
1009
|
+
EasyTalk::Builders::Registry.register(String, EnhancedStringBuilder)
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
#### Registry API
|
|
1013
|
+
|
|
1014
|
+
```ruby
|
|
1015
|
+
# Check if a type is registered
|
|
1016
|
+
EasyTalk::Builders::Registry.registered?(Money) # => true
|
|
1017
|
+
|
|
1018
|
+
# List all registered types
|
|
1019
|
+
EasyTalk::Builders::Registry.registered_types
|
|
1020
|
+
|
|
1021
|
+
# Unregister a type
|
|
1022
|
+
EasyTalk::Builders::Registry.unregister(Money)
|
|
1023
|
+
|
|
1024
|
+
# Reset registry to defaults
|
|
1025
|
+
EasyTalk::Builders::Registry.reset!
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
### Type Introspection
|
|
1029
|
+
|
|
1030
|
+
EasyTalk provides a `TypeIntrospection` module for reliable type detection, useful when building custom type builders:
|
|
1031
|
+
|
|
1032
|
+
```ruby
|
|
1033
|
+
# Check type categories
|
|
1034
|
+
EasyTalk::TypeIntrospection.boolean_type?(T::Boolean) # => true
|
|
1035
|
+
EasyTalk::TypeIntrospection.typed_array?(T::Array[String]) # => true
|
|
1036
|
+
EasyTalk::TypeIntrospection.nilable_type?(T.nilable(String)) # => true
|
|
1037
|
+
EasyTalk::TypeIntrospection.primitive_type?(Integer) # => true
|
|
1038
|
+
|
|
1039
|
+
# Get JSON Schema type string
|
|
1040
|
+
EasyTalk::TypeIntrospection.json_schema_type(Integer) # => 'integer'
|
|
1041
|
+
EasyTalk::TypeIntrospection.json_schema_type(Float) # => 'number'
|
|
1042
|
+
|
|
1043
|
+
# Extract inner type from nilable
|
|
1044
|
+
EasyTalk::TypeIntrospection.extract_inner_type(T.nilable(String)) # => String
|
|
582
1045
|
```
|
|
583
1046
|
|
|
584
1047
|
## Configuration
|
|
@@ -591,11 +1054,20 @@ EasyTalk.configure do |config|
|
|
|
591
1054
|
# Schema behavior options
|
|
592
1055
|
config.default_additional_properties = false # Control additional properties on all models
|
|
593
1056
|
config.nilable_is_optional = false # Makes T.nilable properties also optional
|
|
594
|
-
config.auto_validations = true # Automatically generate ActiveModel validations
|
|
595
1057
|
config.schema_version = :none # JSON Schema version for $schema keyword
|
|
596
1058
|
# Options: :none, :draft202012, :draft201909, :draft7, :draft6, :draft4
|
|
597
1059
|
config.schema_id = nil # Base URI for $id keyword (nil = no $id)
|
|
598
1060
|
config.use_refs = false # Use $ref for nested models instead of inlining
|
|
1061
|
+
config.property_naming_strategy = :camel_case # Options: :identity (default), :snake_case, :camel_case, :pascal_case
|
|
1062
|
+
|
|
1063
|
+
# Validation options
|
|
1064
|
+
config.auto_validations = true # Automatically generate ActiveModel validations
|
|
1065
|
+
config.validation_adapter = :active_model # Validation backend (:active_model, :none, or custom)
|
|
1066
|
+
|
|
1067
|
+
# Error formatting options
|
|
1068
|
+
config.default_error_format = :flat # Default format (:flat, :json_pointer, :rfc7807, :jsonapi)
|
|
1069
|
+
config.error_type_base_uri = 'about:blank' # Base URI for RFC 7807 error types
|
|
1070
|
+
config.include_error_codes = true # Include error codes in formatted output
|
|
599
1071
|
end
|
|
600
1072
|
```
|
|
601
1073
|
|
|
@@ -628,7 +1100,7 @@ You can configure additional properties for individual models:
|
|
|
628
1100
|
```ruby
|
|
629
1101
|
class User
|
|
630
1102
|
include EasyTalk::Model
|
|
631
|
-
|
|
1103
|
+
|
|
632
1104
|
define_schema do
|
|
633
1105
|
title "User"
|
|
634
1106
|
additional_properties true # Allow arbitrary additional properties on this model
|
|
@@ -638,6 +1110,74 @@ class User
|
|
|
638
1110
|
end
|
|
639
1111
|
```
|
|
640
1112
|
|
|
1113
|
+
### Validation Adapters
|
|
1114
|
+
|
|
1115
|
+
EasyTalk uses a pluggable validation adapter system that allows you to customize how validations are generated from schema constraints.
|
|
1116
|
+
|
|
1117
|
+
#### Built-in Adapters
|
|
1118
|
+
|
|
1119
|
+
| Adapter | Description |
|
|
1120
|
+
|---------|-------------|
|
|
1121
|
+
| `:active_model` | Default. Generates ActiveModel validations from schema constraints |
|
|
1122
|
+
| `:none` | Skips validation generation entirely (schema-only mode) |
|
|
1123
|
+
|
|
1124
|
+
#### Global Adapter Configuration
|
|
1125
|
+
|
|
1126
|
+
```ruby
|
|
1127
|
+
EasyTalk.configure do |config|
|
|
1128
|
+
config.validation_adapter = :none # Disable all automatic validations
|
|
1129
|
+
end
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
#### Per-Model Validation Control
|
|
1133
|
+
|
|
1134
|
+
Disable validations for a specific model while keeping them enabled globally:
|
|
1135
|
+
|
|
1136
|
+
```ruby
|
|
1137
|
+
class LegacyModel
|
|
1138
|
+
include EasyTalk::Model
|
|
1139
|
+
|
|
1140
|
+
define_schema(validations: false) do
|
|
1141
|
+
property :data, String, min_length: 1 # No validation generated
|
|
1142
|
+
end
|
|
1143
|
+
end
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
#### Per-Property Validation Control
|
|
1147
|
+
|
|
1148
|
+
Disable validation for specific properties:
|
|
1149
|
+
|
|
1150
|
+
```ruby
|
|
1151
|
+
class User
|
|
1152
|
+
include EasyTalk::Model
|
|
1153
|
+
|
|
1154
|
+
define_schema do
|
|
1155
|
+
property :name, String, min_length: 2 # Validation generated
|
|
1156
|
+
property :legacy_field, String, validate: false # No validation for this property
|
|
1157
|
+
end
|
|
1158
|
+
end
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
#### Custom Validation Adapters
|
|
1162
|
+
|
|
1163
|
+
Create custom adapters for specialized validation needs:
|
|
1164
|
+
|
|
1165
|
+
```ruby
|
|
1166
|
+
class MyCustomAdapter < EasyTalk::ValidationAdapters::Base
|
|
1167
|
+
def self.build_validations(klass, property_name, type, constraints)
|
|
1168
|
+
# Custom validation logic
|
|
1169
|
+
end
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
# Register the adapter
|
|
1173
|
+
EasyTalk::ValidationAdapters::Registry.register(:custom, MyCustomAdapter)
|
|
1174
|
+
|
|
1175
|
+
# Use it globally
|
|
1176
|
+
EasyTalk.configure do |config|
|
|
1177
|
+
config.validation_adapter = :custom
|
|
1178
|
+
end
|
|
1179
|
+
```
|
|
1180
|
+
|
|
641
1181
|
## Examples
|
|
642
1182
|
|
|
643
1183
|
### User Registration (with Auto-Validations)
|
|
@@ -878,18 +1418,18 @@ property :status, String, enum: ["active", "inactive", "pending"]
|
|
|
878
1418
|
9. **Use nullable_optional_property** for fields that can be omitted or null
|
|
879
1419
|
10. **Document breaking changes** when updating schema definitions
|
|
880
1420
|
|
|
881
|
-
|
|
1421
|
+
## Nullable vs Optional Properties in EasyTalk
|
|
882
1422
|
|
|
883
1423
|
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.
|
|
884
1424
|
|
|
885
|
-
|
|
1425
|
+
### Key Concepts
|
|
886
1426
|
|
|
887
1427
|
| Concept | Description | JSON Schema Effect | EasyTalk Syntax |
|
|
888
1428
|
|---------|-------------|-------------------|-----------------|
|
|
889
1429
|
| **Nullable** | Property can have a `null` value | Adds `"null"` to the type array | `T.nilable(Type)` |
|
|
890
1430
|
| **Optional** | Property doesn't have to exist | Omits property from `"required"` array | `optional: true` constraint |
|
|
891
1431
|
|
|
892
|
-
|
|
1432
|
+
### Nullable Properties
|
|
893
1433
|
|
|
894
1434
|
A **nullable** property can contain a `null` value, but the property itself must still be present in the object:
|
|
895
1435
|
|
|
@@ -915,7 +1455,7 @@ In this case, the following data would be valid:
|
|
|
915
1455
|
But this would be invalid:
|
|
916
1456
|
- `{ }` (missing the age property entirely)
|
|
917
1457
|
|
|
918
|
-
|
|
1458
|
+
### Optional Properties
|
|
919
1459
|
|
|
920
1460
|
An **optional** property doesn't have to be present in the object at all:
|
|
921
1461
|
|
|
@@ -941,7 +1481,7 @@ In this case, the following data would be valid:
|
|
|
941
1481
|
But this would be invalid:
|
|
942
1482
|
- `{ "nickname": null }` (null is not allowed because the property isn't nullable)
|
|
943
1483
|
|
|
944
|
-
|
|
1484
|
+
### Nullable AND Optional Properties
|
|
945
1485
|
|
|
946
1486
|
For properties that should be both nullable and optional (can be omitted or null), you need to combine both approaches:
|
|
947
1487
|
|
|
@@ -968,7 +1508,7 @@ nullable_optional_property :bio, String
|
|
|
968
1508
|
|
|
969
1509
|
Which is equivalent to the above.
|
|
970
1510
|
|
|
971
|
-
|
|
1511
|
+
### Configuration Options
|
|
972
1512
|
|
|
973
1513
|
By default, nullable properties are still required. You can change this global behavior:
|
|
974
1514
|
|
|
@@ -980,9 +1520,9 @@ end
|
|
|
980
1520
|
|
|
981
1521
|
With this configuration, any property defined with `T.nilable(Type)` will be treated as both nullable and optional.
|
|
982
1522
|
|
|
983
|
-
|
|
1523
|
+
### Practical Examples
|
|
984
1524
|
|
|
985
|
-
|
|
1525
|
+
#### User Profile Schema
|
|
986
1526
|
|
|
987
1527
|
```ruby
|
|
988
1528
|
class UserProfile
|
|
@@ -1011,17 +1551,17 @@ This creates clear expectations for data validation:
|
|
|
1011
1551
|
- `email` doesn't have to be present, but if it is, it cannot be null
|
|
1012
1552
|
- `bio` doesn't have to be present, and if it is, it can be null
|
|
1013
1553
|
|
|
1014
|
-
|
|
1554
|
+
### Common Gotchas
|
|
1015
1555
|
|
|
1016
|
-
|
|
1556
|
+
#### Misconception: Nullable Implies Optional
|
|
1017
1557
|
|
|
1018
1558
|
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.
|
|
1019
1559
|
|
|
1020
|
-
|
|
1560
|
+
#### Misconception: Optional Properties Accept Null
|
|
1021
1561
|
|
|
1022
1562
|
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)`.
|
|
1023
1563
|
|
|
1024
|
-
|
|
1564
|
+
### Migration from Earlier Versions
|
|
1025
1565
|
|
|
1026
1566
|
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.
|
|
1027
1567
|
|
|
@@ -1035,14 +1575,14 @@ end
|
|
|
1035
1575
|
|
|
1036
1576
|
We recommend updating your schema definitions to explicitly declare which properties are optional using the `optional: true` constraint, as this makes your intent clearer.
|
|
1037
1577
|
|
|
1038
|
-
|
|
1578
|
+
### Best Practices
|
|
1039
1579
|
|
|
1040
1580
|
1. **Be explicit about intent**: Always clarify whether properties should be nullable, optional, or both
|
|
1041
1581
|
2. **Use the helper method**: For properties that are both nullable and optional, use `nullable_optional_property`
|
|
1042
1582
|
3. **Document expectations**: Use comments to clarify validation requirements for complex schemas
|
|
1043
1583
|
4. **Consider validation implications**: Remember that ActiveModel validations operate independently of the schema definition
|
|
1044
1584
|
|
|
1045
|
-
|
|
1585
|
+
### JSON Schema Comparison
|
|
1046
1586
|
|
|
1047
1587
|
| EasyTalk Definition | Required | Nullable | JSON Schema Equivalent |
|
|
1048
1588
|
|--------------------|----------|----------|------------------------|
|
|
@@ -1828,6 +2368,47 @@ To learn about current capabilities, see the [spec/easy_talk/examples](https://g
|
|
|
1828
2368
|
- Some draft-specific keywords may not be supported
|
|
1829
2369
|
- Complex composition scenarios may require manual adjustment
|
|
1830
2370
|
|
|
2371
|
+
## API Reference
|
|
2372
|
+
|
|
2373
|
+
For complete API documentation, visit [RubyDoc.info](https://rubydoc.info/gems/easy_talk).
|
|
2374
|
+
|
|
2375
|
+
### Core Modules
|
|
2376
|
+
|
|
2377
|
+
| Module | Description | Source |
|
|
2378
|
+
|--------|-------------|--------|
|
|
2379
|
+
| [`EasyTalk::Model`](https://rubydoc.info/gems/easy_talk/EasyTalk/Model) | Main mixin providing schema definition, validation, and JSON Schema generation | [lib/easy_talk/model.rb](lib/easy_talk/model.rb) |
|
|
2380
|
+
| [`EasyTalk::Schema`](https://rubydoc.info/gems/easy_talk/EasyTalk/Schema) | Schema-only mode without ActiveModel validations | [lib/easy_talk/schema.rb](lib/easy_talk/schema.rb) |
|
|
2381
|
+
| [`EasyTalk::SchemaDefinition`](https://rubydoc.info/gems/easy_talk/EasyTalk/SchemaDefinition) | DSL for defining properties, titles, and descriptions | [lib/easy_talk/schema_definition.rb](lib/easy_talk/schema_definition.rb) |
|
|
2382
|
+
| [`EasyTalk::Property`](https://rubydoc.info/gems/easy_talk/EasyTalk/Property) | Property definition and type dispatching | [lib/easy_talk/property.rb](lib/easy_talk/property.rb) |
|
|
2383
|
+
|
|
2384
|
+
### Builders
|
|
2385
|
+
|
|
2386
|
+
Type-specific builders that convert Ruby definitions to JSON Schema. See the [builders directory](lib/easy_talk/builders/) for all available builders.
|
|
2387
|
+
|
|
2388
|
+
| Builder | Description |
|
|
2389
|
+
|---------|-------------|
|
|
2390
|
+
| [`ObjectBuilder`](lib/easy_talk/builders/object_builder.rb) | Handles EasyTalk::Model classes |
|
|
2391
|
+
| [`StringBuilder`](lib/easy_talk/builders/string_builder.rb) | String type with format, pattern, length constraints |
|
|
2392
|
+
| [`IntegerBuilder`](lib/easy_talk/builders/integer_builder.rb) | Integer type with min/max constraints |
|
|
2393
|
+
| [`NumberBuilder`](lib/easy_talk/builders/number_builder.rb) | Float/Number type with numeric constraints |
|
|
2394
|
+
| [`BooleanBuilder`](lib/easy_talk/builders/boolean_builder.rb) | Boolean type (T::Boolean) |
|
|
2395
|
+
| [`TypedArrayBuilder`](lib/easy_talk/builders/typed_array_builder.rb) | Typed arrays (T::Array[Type]) |
|
|
2396
|
+
| [`CompositionBuilder`](lib/easy_talk/builders/composition_builder.rb) | Composition types (T::AnyOf, T::OneOf, T::AllOf) |
|
|
2397
|
+
| [`UnionBuilder`](lib/easy_talk/builders/union_builder.rb) | Nilable types (T.nilable) |
|
|
2398
|
+
| [`TemporalBuilder`](lib/easy_talk/builders/temporal_builder.rb) | Date and DateTime types |
|
|
2399
|
+
| [`BaseBuilder`](lib/easy_talk/builders/base_builder.rb) | Base class for all builders |
|
|
2400
|
+
| [`Registry`](lib/easy_talk/builders/registry.rb) | Type-to-builder registration |
|
|
2401
|
+
|
|
2402
|
+
### Configuration & Utilities
|
|
2403
|
+
|
|
2404
|
+
| Class/Module | Description | Source |
|
|
2405
|
+
|--------------|-------------|--------|
|
|
2406
|
+
| [`EasyTalk::Configuration`](https://rubydoc.info/gems/easy_talk/EasyTalk/Configuration) | Global configuration options | [lib/easy_talk/configuration.rb](lib/easy_talk/configuration.rb) |
|
|
2407
|
+
| [`EasyTalk::ValidationBuilder`](https://rubydoc.info/gems/easy_talk/EasyTalk/ValidationBuilder) | Generates ActiveModel validations from constraints | [lib/easy_talk/validation_builder.rb](lib/easy_talk/validation_builder.rb) |
|
|
2408
|
+
| [`EasyTalk::ErrorFormatter`](https://rubydoc.info/gems/easy_talk/EasyTalk/ErrorFormatter) | Formats validation errors (flat, JSON Pointer, RFC 7807, JSON:API) | [lib/easy_talk/error_formatter.rb](lib/easy_talk/error_formatter.rb) |
|
|
2409
|
+
| [`EasyTalk::TypeIntrospection`](https://rubydoc.info/gems/easy_talk/EasyTalk/TypeIntrospection) | Type detection utilities | [lib/easy_talk/type_introspection.rb](lib/easy_talk/type_introspection.rb) |
|
|
2410
|
+
| [`EasyTalk::Tools::FunctionBuilder`](https://rubydoc.info/gems/easy_talk/EasyTalk/Tools/FunctionBuilder) | LLM function specification generator | [lib/easy_talk/tools/function_builder.rb](lib/easy_talk/tools/function_builder.rb) |
|
|
2411
|
+
|
|
1831
2412
|
## License
|
|
1832
2413
|
|
|
1833
2414
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|