schema_dot_org 2.5.0 → 2.5.1

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: eba4af5a8f17ea83c93f00956aeb53733a629a2a7dff60a20774f52b4682c5a2
4
- data.tar.gz: a7f134544c69e830613e9004ac8bee7e8944637270f0f39c569d91cbd2fe1cef
3
+ metadata.gz: 51ce5547733a21842002c07e64f087879b748fc0aca5f38be3b1719050b44eb8
4
+ data.tar.gz: 847aa9795b17a6903e6a8380ad24e11ae74f14db46225c6bf78965ec585c67a6
5
5
  SHA512:
6
- metadata.gz: f840e728482eca79bca2035002fb6f1cd47fb5b41e54ec823ea17dfd6ad2988f9c51d7b82414004a39d3637ae56c80509bf2425cf4373854d00a469e35daa284
7
- data.tar.gz: a06b1d8b8da895c7713ded7a913d6ee069ff7205ae3f4f3fe13b25bf6f6c7ee2af98fac885d761889b1a09a136f31e37c68bd4295c8ee324917558c6a6c40cca
6
+ metadata.gz: e5b6d909e5edd6999ee5051f1df5b0b8c5f5274172b1f602be3c17e2a5c0fcad9c0499e930e9a757c5c42d62597af4b2e8c89898c534008f63172567113cb53f
7
+ data.tar.gz: 04e8ef548d8dcf6dfb2e077fc759a472d29fe0da8a28a28b69b23e79b900daeebaa192d1e55c645dee169381252c20bba14930f2d6f4ecd8a42b93bb127e3aab
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## 2.5.1
2
+
3
+ * New Type: PostalAddress
4
+ * Add PostalAddress to Organization.address
5
+ * Add PostalAddress to Place.address
6
+ * Add support for type unions
7
+ * Add support for typed arrays
data/CLAUDE.md ADDED
@@ -0,0 +1,91 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ This is a Ruby gem that generates structured data (JSON-LD) for Schema.org types. It provides strongly-typed Ruby classes that validate their attributes and output valid Schema.org markup for SEO and search enhancement.
8
+
9
+ ## Development Commands
10
+
11
+ ### Testing
12
+ - `bundle exec rake spec` or `bundle exec rspec` - Run all RSpec tests
13
+ - `bundle exec rspec spec/schema_dot_org/[type]_spec.rb` - Run tests for a specific Schema.org type
14
+ - `bundle exec rake` - Run default task (runs tests)
15
+
16
+ ### Gem Management
17
+ - `gem build schema_dot_org.gemspec` - Build the gem locally
18
+ - `gem install ./schema_dot_org-[version].gem` - Install built gem locally
19
+ - `bundle install` - Install dependencies
20
+
21
+ ### Interactive Development
22
+ - `bundle exec pry` - Start Pry REPL with gem loaded for interactive testing
23
+
24
+ ## Architecture
25
+
26
+ ### Core Components
27
+
28
+ **SchemaType Base Class** (`lib/schema_dot_org.rb`):
29
+ - Abstract base class for all Schema.org types
30
+ - Handles JSON-LD generation with `to_json_ld()` and `to_s()` methods
31
+ - Converts snake_case Ruby attributes to camelCase JSON-LD
32
+ - Provides validation through ValidatedObject gem integration
33
+ - Automatically adds `@context` and `@type` fields
34
+
35
+ **Schema.org Type Classes** (`lib/schema_dot_org/*.rb`):
36
+ - Each file represents one Schema.org type (Organization, Person, BreadcrumbList, etc.)
37
+ - Classes inherit from SchemaType and use `validated_attr` for type-safe attributes
38
+ - Follow pattern: `validated_attr :attribute_name, type: [Type], allow_nil: true/false`
39
+
40
+ **URL Validation** (`lib/schema_dot_org/url_validator.rb`):
41
+ - Validates URLs used in structured data
42
+ - Used by convenience methods like `make_breadcrumbs`
43
+
44
+ ### Design Patterns
45
+
46
+ **Validation-First Approach**:
47
+ - All attributes are validated at object creation time
48
+ - Invalid data causes immediate ArgumentError/NoMethodError rather than silent failures
49
+ - Uses ActiveRecord-style validations via ValidatedObject gem
50
+
51
+ **Declarative Attribute Definition**:
52
+ ```ruby
53
+ class Product < SchemaType
54
+ validated_attr :name, type: String
55
+ validated_attr :description, type: String, allow_nil: true
56
+ validated_attr :offers, type: SchemaDotOrg::AggregateOffer
57
+ end
58
+ ```
59
+
60
+ **Nested Schema Types**:
61
+ - Schema types can reference other schema types as attributes
62
+ - Automatic JSON-LD nesting handled by base class
63
+ - Example: Organization can have Person founder, Place founding_location
64
+
65
+ ### Key Files Structure
66
+
67
+ - `lib/schema_dot_org.rb` - Main module, base SchemaType class, convenience methods
68
+ - `lib/schema_dot_org/[type].rb` - Individual Schema.org type implementations
69
+ - `spec/schema_dot_org/[type]_spec.rb` - RSpec tests for each type
70
+ - `spec/spec_helper.rb` - RSpec configuration with doctest2 integration
71
+
72
+ ### Testing Patterns
73
+
74
+ - Each Schema.org type has corresponding RSpec test file
75
+ - Tests validate both successful creation and error conditions
76
+ - Tests verify correct JSON-LD output format
77
+ - Uses doctest2-rspec for testing code examples in comments
78
+
79
+ ## Adding New Schema.org Types
80
+
81
+ 1. Create new file `lib/schema_dot_org/new_type.rb`
82
+ 2. Define class inheriting from SchemaType with validated_attr declarations
83
+ 3. Add require statement to main `lib/schema_dot_org.rb` file
84
+ 4. Create corresponding test file `spec/schema_dot_org/new_type_spec.rb`
85
+ 5. Follow existing patterns for validation and JSON-LD output testing
86
+
87
+ ## Dependencies
88
+
89
+ - **validated_object (~> 2.3)** - Provides ActiveRecord-style validations
90
+ - **rspec (~> 3.12)** - Testing framework
91
+ - **doctest2-rspec (~> 0.9.2)** - Tests code examples in documentation
data/Gemfile.lock CHANGED
@@ -1,65 +1,67 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schema_dot_org (2.5.0)
5
- validated_object (~> 2.3)
4
+ schema_dot_org (2.5.1)
5
+ validated_object (~> 2.3.4)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activemodel (7.1.1)
11
- activesupport (= 7.1.1)
12
- activesupport (7.1.1)
10
+ activemodel (8.0.2.1)
11
+ activesupport (= 8.0.2.1)
12
+ activesupport (8.0.2.1)
13
13
  base64
14
+ benchmark (>= 0.3)
14
15
  bigdecimal
15
- concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ concurrent-ruby (~> 1.0, >= 1.3.1)
16
17
  connection_pool (>= 2.2.5)
17
18
  drb
18
19
  i18n (>= 1.6, < 2)
20
+ logger (>= 1.4.2)
19
21
  minitest (>= 5.1)
20
- mutex_m
21
- tzinfo (~> 2.0)
22
- base64 (0.1.1)
23
- bigdecimal (3.1.4)
22
+ securerandom (>= 0.3)
23
+ tzinfo (~> 2.0, >= 2.0.5)
24
+ uri (>= 0.13.1)
25
+ base64 (0.3.0)
26
+ benchmark (0.4.1)
27
+ bigdecimal (3.2.2)
24
28
  coderay (1.1.3)
25
- concurrent-ruby (1.2.2)
26
- connection_pool (2.4.1)
27
- diff-lcs (1.5.0)
29
+ concurrent-ruby (1.3.5)
30
+ connection_pool (2.5.3)
31
+ diff-lcs (1.6.2)
28
32
  doctest2-core (0.9.3)
29
33
  doctest2-rspec (0.9.2)
30
34
  doctest2-core (~> 0.9.0)
31
35
  rspec (~> 3.0)
32
- drb (2.1.1)
33
- ruby2_keywords
34
- i18n (1.14.1)
36
+ drb (2.2.3)
37
+ i18n (1.14.7)
35
38
  concurrent-ruby (~> 1.0)
39
+ logger (1.7.0)
36
40
  method_source (1.1.0)
37
- minitest (5.20.0)
38
- mutex_m (0.1.2)
41
+ minitest (5.25.5)
39
42
  pry (0.15.2)
40
43
  coderay (~> 1.1)
41
44
  method_source (~> 1.0)
42
- rake (13.0.6)
43
- rspec (3.12.0)
44
- rspec-core (~> 3.12.0)
45
- rspec-expectations (~> 3.12.0)
46
- rspec-mocks (~> 3.12.0)
47
- rspec-core (3.12.2)
48
- rspec-support (~> 3.12.0)
49
- rspec-expectations (3.12.3)
45
+ rake (13.3.0)
46
+ rspec (3.13.1)
47
+ rspec-core (~> 3.13.0)
48
+ rspec-expectations (~> 3.13.0)
49
+ rspec-mocks (~> 3.13.0)
50
+ rspec-core (3.13.5)
51
+ rspec-support (~> 3.13.0)
52
+ rspec-expectations (3.13.5)
50
53
  diff-lcs (>= 1.2.0, < 2.0)
51
- rspec-support (~> 3.12.0)
52
- rspec-mocks (3.12.6)
54
+ rspec-support (~> 3.13.0)
55
+ rspec-mocks (3.13.5)
53
56
  diff-lcs (>= 1.2.0, < 2.0)
54
- rspec-support (~> 3.12.0)
55
- rspec-support (3.12.1)
56
- ruby2_keywords (0.0.5)
57
- sorbet-runtime (0.5.11072)
57
+ rspec-support (~> 3.13.0)
58
+ rspec-support (3.13.5)
59
+ securerandom (0.4.1)
58
60
  tzinfo (2.0.6)
59
61
  concurrent-ruby (~> 1.0)
60
- validated_object (2.3.0)
62
+ uri (1.0.3)
63
+ validated_object (2.3.4)
61
64
  activemodel (>= 3.2.21)
62
- sorbet-runtime (>= 0.5.5890)
63
65
 
64
66
  PLATFORMS
65
67
  arm64-darwin-24
data/README.md CHANGED
@@ -8,7 +8,6 @@
8
8
  - [Examples](#examples)
9
9
  - [BreadcrumbList](#breadcrumblist)
10
10
  - [WebSite](#website)
11
- - [Organization](#organization)
12
11
  - [Installation](#installation)
13
12
  - [Development](#development)
14
13
  - [Contributing](#contributing)
@@ -141,6 +140,7 @@ See each type's RSpec for an example of how to use it.
141
140
  | Organization | [Schema.org](https://schema.org/Organization) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/organization_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/organization.rb) |
142
141
  | Person | [Schema.org](https://schema.org/Person) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/person_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/person.rb) |
143
142
  | Place | [Schema.org](https://schema.org/Place) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/place_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/place.rb) |
143
+ | PostalAddress | [Schema.org](https://schema.org/PostalAddress) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/postal_address_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/postal_address.rb) |
144
144
  | Product | [Schema.org](https://schema.org/Product) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/product_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/product.rb) |
145
145
  | SearchAction | [Schema.org](https://schema.org/SearchAction) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/search_action_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/search_action.rb) |
146
146
  | WebSite | [Schema.org](https://schema.org/WebSite) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/web_site_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/web_site.rb) |
@@ -226,26 +226,6 @@ WebSite.new(
226
226
  )
227
227
  ```
228
228
 
229
- ### Organization
230
-
231
- Example:
232
-
233
- ```ruby
234
- Organization.new(
235
- name: 'Public.Law',
236
- founder: Person.new(name: 'Robb Shecter'),
237
- founding_date: Date.new(2009, 3, 6),
238
- founding_location: Place.new(address: 'Portland, OR'),
239
- email: 'say_hi@public.law',
240
- url: 'https://www.public.law',
241
- logo: 'https://www.public.law/favicon-196x196.png',
242
- same_as: [
243
- 'https://twitter.com/law_is_code',
244
- 'https://www.facebook.com/PublicDotLaw'
245
- ]
246
- )
247
- ```
248
-
249
229
 
250
230
  ## Installation
251
231
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'date'
4
4
  require_relative 'person'
5
+ require_relative 'organization'
5
6
 
6
7
  #
7
8
  # Model the Schema.org `Thing > CreativeWork > Article > SocialMediaPosting > DiscussionForumPosting`.
@@ -9,10 +10,8 @@ require_relative 'person'
9
10
  #
10
11
  module SchemaDotOrg
11
12
  class DiscussionForumPosting < SchemaType
12
- # TODO: Allow for type Person or Organization
13
- validated_attr :author, type: Person, presence: true
14
- # TODO: Allow for type Date or DateTime
15
- validated_attr :datePublished, type: Date, presence: true
13
+ validated_attr :author, type: union(Person, Organization), presence: true
14
+ validated_attr :datePublished, type: union(Date, Time), presence: true
16
15
 
17
16
  validated_attr :comment, type: Array, allow_nil: true
18
17
  validated_attr :commentCount, type: Integer, allow_nil: true
@@ -4,12 +4,14 @@ require 'date'
4
4
 
5
5
  require_relative 'person'
6
6
  require_relative 'place'
7
+ require_relative 'postal_address'
7
8
 
8
9
  # Google allows `url` to be a string:
9
10
  # https://developers.google.com/search/docs/appearance/structured-data/logo
10
11
 
11
12
  module SchemaDotOrg
12
13
  class Organization < SchemaType
14
+ validated_attr :address, type: SchemaDotOrg::PostalAddress, allow_nil: true
13
15
  validated_attr :contact_points, type: Array, allow_nil: true
14
16
  validated_attr :email, type: String, allow_nil: true
15
17
  validated_attr :founder, type: SchemaDotOrg::Person, allow_nil: true
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'postal_address'
4
+
3
5
 
4
6
  #
5
7
  # Model the Schema.org `Thing > Place`. See http://schema.org/Place
6
8
  #
7
9
  module SchemaDotOrg
8
10
  class Place < SchemaType
9
- validated_attr :address, type: String, presence: true
11
+ validated_attr :address, type: union(String, SchemaDotOrg::PostalAddress), presence: true
10
12
  end
11
13
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Model the Schema.org `Thing > Intangible > StructuredValue > ContactPoint > PostalAddress`.
5
+ # See https://schema.org/PostalAddress
6
+ #
7
+ module SchemaDotOrg
8
+ class PostalAddress < SchemaType
9
+
10
+ # AddressCountry: The country. Recommended to be in 2-letter ISO 3166-1 alpha-2
11
+ # format, for example "US". For backward compatibility, a 3-letter ISO 3166-1 alpha-3
12
+ # country code such as "SGP" or a full country name such as "Singapore" can also be
13
+ # used.
14
+ validated_attr :addressCountry, type: String, allow_nil: true
15
+
16
+ # AddressLocality: The locality in which the street address is,
17
+ # and which is in the region. For example, Mountain View.
18
+ validated_attr :addressLocality, type: String, allow_nil: true
19
+
20
+ # AddressRegion: The region in which the locality is, and which is in the country.
21
+ # For example, California or another appropriate first-level Administrative division.
22
+ validated_attr :addressRegion, type: String, allow_nil: true
23
+
24
+ # ExtendedAddress: An address extension such as an apartment number, C/O or
25
+ # alternative name.
26
+ validated_attr :extendedAddress, type: String, allow_nil: true
27
+
28
+ # PostalCode: The postal code. For example, 94043.
29
+ validated_attr :postalCode, type: String, allow_nil: true
30
+
31
+ # StreetAddress: The street address. For example, 1600 Amphitheatre Parkway.
32
+ validated_attr :streetAddress, type: String, allow_nil: true
33
+ end
34
+ end
@@ -159,6 +159,7 @@ require 'schema_dot_org/list_item'
159
159
  require 'schema_dot_org/organization'
160
160
  require 'schema_dot_org/person'
161
161
  require 'schema_dot_org/place'
162
+ require 'schema_dot_org/postal_address'
162
163
  require 'schema_dot_org/product'
163
164
  require 'schema_dot_org/offer'
164
165
  require 'schema_dot_org/search_action'
@@ -5,9 +5,9 @@ lib = File.expand_path('lib', __dir__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.required_ruby_version = '>= 3.0'
8
+ spec.required_ruby_version = '>= 3.1'
9
9
  spec.name = 'schema_dot_org'
10
- spec.version = '2.5.0'
10
+ spec.version = '2.5.1'
11
11
  spec.authors = ['Robert Shecter']
12
12
  spec.email = ['robert@public.law']
13
13
 
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
- spec.add_dependency 'validated_object', '~> 2.3'
28
+ spec.add_dependency 'validated_object', '~> 2.3.4'
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 2.4"
31
31
  spec.add_development_dependency "rake", "~> 13.0"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema_dot_org
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Shecter
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '2.3'
18
+ version: 2.3.4
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '2.3'
25
+ version: 2.3.4
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: bundler
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,8 @@ files:
103
103
  - ".gitignore"
104
104
  - ".rspec"
105
105
  - ".travis.yml"
106
+ - CHANGELOG.md
107
+ - CLAUDE.md
106
108
  - Gemfile
107
109
  - Gemfile.lock
108
110
  - LICENSE.txt
@@ -126,6 +128,7 @@ files:
126
128
  - lib/schema_dot_org/organization.rb
127
129
  - lib/schema_dot_org/person.rb
128
130
  - lib/schema_dot_org/place.rb
131
+ - lib/schema_dot_org/postal_address.rb
129
132
  - lib/schema_dot_org/product.rb
130
133
  - lib/schema_dot_org/search_action.rb
131
134
  - lib/schema_dot_org/url_validator.rb
@@ -143,14 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
146
  requirements:
144
147
  - - ">="
145
148
  - !ruby/object:Gem::Version
146
- version: '3.0'
149
+ version: '3.1'
147
150
  required_rubygems_version: !ruby/object:Gem::Requirement
148
151
  requirements:
149
152
  - - ">="
150
153
  - !ruby/object:Gem::Version
151
154
  version: '0'
152
155
  requirements: []
153
- rubygems_version: 3.6.9
156
+ rubygems_version: 3.7.1
154
157
  specification_version: 4
155
158
  summary: JSON-LD generator for Schema.org vocabulary
156
159
  test_files: []