easy_talk 0.1.8 → 0.1.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da6e2b2c29860236280b654d18e4df4af908ab0246f01e1e5e376805f8359d37
4
- data.tar.gz: 1a36d4e08f82069391386c3b2bd03becfeaea198657b8db05ff2ebda793d4ec8
3
+ metadata.gz: 1ebe87803e47220d1a3f6396a1735fd2aa04b3f2b1428bea43cd873cb32f3bca
4
+ data.tar.gz: ecdaaa2801742335160a89a38a92ef9b402be563d3ce0e54c52f3068d75c93ce
5
5
  SHA512:
6
- metadata.gz: 9026006c5e296adf2f3a7c826757ffe4b17a1387c3621907442ac47293d2d7d89eb4779fe3863ef24f6a8fc34174a7b4e7e22d2aaf0a26a4534ddc65f08ab482
7
- data.tar.gz: d3cd70fb2ac65241cf395606d0eae55e2282006578f4f78096f9e03256ae6fa91bd371b0874d20aa797667b4972be4ff91c5b38b4396ee1be89a3b4d057d4681
6
+ metadata.gz: 866e44d124957d2149bd67584c0e35129bd922c98da0bb9d4b37cead66636d84b508290be35b4ce79ad3940bd556585ee604aeb79c220f898450624765e3fd50
7
+ data.tar.gz: 551cd5c6f3de517efd56fadb407fd723de14764d3520b7be7ee73e12a7027d391816452ad13a00752e0fa690d5da2eef4aff2d0b12b585ed686eeb31635875ac
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [0.1.10] - 2024-04-29
2
+ - Accept `:optional` key as constraint which excludes property from required node.
3
+ - Spec fixes
4
+ ## [0.1.9] - 2024-04-29
5
+ - Added the ability to describe an object schema withing the define_schema block. Example:
6
+ ```ruby
7
+ ...
8
+ property :email, :object do
9
+ property :address, :string
10
+ property :verified, :boolean
11
+ end
12
+ ```
13
+
1
14
  ## [0.1.8] - 2024-04-24
2
15
  - mostly refactoring without changes to the public API.
3
16
 
data/README.md CHANGED
@@ -12,7 +12,10 @@ class User
12
12
  title "User"
13
13
  description "A user of the system"
14
14
  property :name, String, description: "The user's name", title: "Full Name"
15
- property :email, String, description: "The user's email", format: "email", title: "Email Address"
15
+ property :email, :object do
16
+ property :address, String, format: "email", description: "The user's email", title: "Email Address"
17
+ property :verified, T::Boolean, description: "Whether the email is verified"
18
+ end
16
19
  property :group, String, enum: [1, 2, 3], default: 1, description: "The user's group"
17
20
  property :age, Integer, minimum: 18, maximum: 100, description: "The user's age"
18
21
  property :tags, T::Array[String], min_items: 1, unique_item: true, description: "The user's tags"
@@ -34,10 +37,23 @@ Calling `User.json_schema` will return the JSON Schema for the User class:
34
37
  "type": "string"
35
38
  },
36
39
  "email": {
37
- "title": "Email Address",
38
- "description": "The user's email",
39
- "type": "string",
40
- "format": "email"
40
+ "type": "object",
41
+ "properties": {
42
+ "address": {
43
+ "title": "Email Address",
44
+ "description": "The user's email",
45
+ "type": "string",
46
+ "format": "email"
47
+ },
48
+ "verified": {
49
+ "type": "boolean",
50
+ "description": "Whether the email is verified"
51
+ }
52
+ },
53
+ "required": [
54
+ "address",
55
+ "verified"
56
+ ]
41
57
  },
42
58
  "group": {
43
59
  "type": "number",
@@ -11,7 +11,8 @@ module EasyTalk
11
11
  # representing schema properties.
12
12
  COMMON_OPTIONS = {
13
13
  title: { type: T.nilable(String), key: :title },
14
- description: { type: T.nilable(String), key: :description }
14
+ description: { type: T.nilable(String), key: :description },
15
+ optional: { type: T.nilable(T::Boolean), key: :optional }
15
16
  }.freeze
16
17
 
17
18
  attr_reader :name, :schema, :options
@@ -11,10 +11,10 @@ module EasyTalk
11
11
  attr_reader :schema
12
12
 
13
13
  VALID_OPTIONS = {
14
- properties: { type: T::Hash[Symbol, T.untyped], key: :properties },
14
+ properties: { type: T::Hash[T.any(Symbol, String), T.untyped], key: :properties },
15
15
  additional_properties: { type: T::Boolean, key: :additionalProperties },
16
16
  subschemas: { type: T::Array[T.untyped], key: :subschemas },
17
- required: { type: T::Array[Symbol], key: :required },
17
+ required: { type: T::Array[T.any(Symbol, String)], key: :required },
18
18
  defs: { type: T.untyped, key: :$defs },
19
19
  allOf: { type: T.untyped, key: :allOf },
20
20
  anyOf: { type: T.untyped, key: :anyOf },
@@ -33,42 +33,60 @@ module EasyTalk
33
33
 
34
34
  private
35
35
 
36
- def properties_from_schema_definition(properties)
36
+ def properties_from_schema_definition
37
+ properties = schema.delete(:properties) || {}
37
38
  properties.each_with_object({}) do |(property_name, options), context|
38
- @required_properties << property_name unless options[:type].respond_to?(:nilable?) && options[:type].nilable?
39
- context[property_name] = Property.new(property_name, options[:type], options[:constraints])
39
+ add_required_property(property_name, options)
40
+ context[property_name] = build_property(property_name, options)
40
41
  end
41
42
  end
42
43
 
43
- def subschemas_from_schema_definition(subschemas)
44
+ def add_required_property(property_name, options)
45
+ return if options.is_a?(Hash) && !!(options[:type].respond_to?(:nilable?) && options[:type].nilable?)
46
+
47
+ return if options.respond_to?(:optional?) && options.optional?
48
+
49
+ @required_properties << property_name
50
+ end
51
+
52
+ def build_property(property_name, options)
53
+ if options.is_a?(EasyTalk::SchemaDefinition)
54
+ ObjectBuilder.new(options).build
55
+ else
56
+ Property.new(property_name, options[:type], options[:constraints])
57
+ end
58
+ end
59
+
60
+ def subschemas_from_schema_definition
61
+ subschemas = schema.delete(:subschemas) || []
44
62
  subschemas.each do |subschema|
45
- definitions = subschema.items.each_with_object({}) do |item, hash|
46
- hash[item.name] = item.schema
47
- end
48
- schema[:defs] = definitions
49
- references = subschema.items.map do |item|
50
- { '$ref': item.ref_template }
51
- end
52
- schema[subschema.name] = references
63
+ add_definitions(subschema)
64
+ add_references(subschema)
53
65
  end
54
66
  end
55
67
 
68
+ def add_definitions(subschema)
69
+ definitions = subschema.items.each_with_object({}) do |item, hash|
70
+ hash[item.name] = item.schema
71
+ end
72
+ schema[:defs] = definitions
73
+ end
74
+
75
+ def add_references(subschema)
76
+ references = subschema.items.map do |item|
77
+ { '$ref': item.ref_template }
78
+ end
79
+ schema[subschema.name] = references
80
+ end
81
+
56
82
  def options
57
- subschemas_from_schema_definition(subschemas)
58
83
  @options = schema
59
- @options[:properties] = properties_from_schema_definition(properties)
84
+ subschemas_from_schema_definition
85
+ @options[:properties] = properties_from_schema_definition
60
86
  @options[:required] = @required_properties
61
87
  @options.reject! { |_key, value| [nil, [], {}].include?(value) }
62
88
  @options
63
89
  end
64
-
65
- def properties
66
- schema.delete(:properties) || {}
67
- end
68
-
69
- def subschemas
70
- schema.delete(:subschemas) || []
71
- end
72
90
  end
73
91
  end
74
92
  end
@@ -15,7 +15,8 @@ module EasyTalk
15
15
  max_length: { type: Integer, key: :maxLength },
16
16
  enum: { type: T::Array[String], key: :enum },
17
17
  const: { type: String, key: :const },
18
- default: { type: String, key: :default }
18
+ default: { type: String, key: :default },
19
+ optional: { type: T::Boolean, key: :optional }
19
20
  }.freeze
20
21
 
21
22
  sig { params(name: Symbol, constraints: Hash).void }
@@ -16,8 +16,8 @@ module EasyTalk
16
16
 
17
17
  attr_reader :name, :schema
18
18
 
19
- def initialize(name)
20
- @schema = {}
19
+ def initialize(name, schema = {})
20
+ @schema = schema
21
21
  @name = name
22
22
  end
23
23
 
@@ -32,10 +32,23 @@ module EasyTalk
32
32
  @schema[:subschemas] += subschemas
33
33
  end
34
34
 
35
- sig { params(name: Symbol, type: T.untyped, constraints: T.untyped).void }
36
- def property(name, type, **constraints)
35
+ sig do
36
+ params(name: T.any(Symbol, String), type: T.untyped, constraints: T.untyped, blk: T.nilable(T.proc.void)).void
37
+ end
38
+ def property(name, type, **constraints, &blk)
37
39
  @schema[:properties] ||= {}
38
- @schema[:properties][name] = { type:, constraints: }
40
+
41
+ if block_given?
42
+ property_schema = SchemaDefinition.new(name, constraints)
43
+ property_schema.instance_eval(&blk)
44
+ @schema[:properties][name] = property_schema
45
+ else
46
+ @schema[:properties][name] = { type:, constraints: }
47
+ end
48
+ end
49
+
50
+ def optional?
51
+ @schema[:optional]
39
52
  end
40
53
  end
41
54
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EasyTalk
4
- VERSION = '0.1.8'
4
+ VERSION = '0.1.10'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_talk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio Bayona
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-24 00:00:00.000000000 Z
11
+ date: 2024-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport