route_schemer 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4dd45bbb9e2f0add1fece5dcd0ba7a6ecc66c245655d65e0f329527e07c05506
4
+ data.tar.gz: fd8fa2f8f99f2e2c7b3fb56933610fa2f73483d47b8df226c8055dbd8cd54818
5
+ SHA512:
6
+ metadata.gz: 634b3f5be853503903704a688bc2e1d5bad7dcd74940aaaecb2a68a51dd02623d3b16a4d1f8ab0e43ca78c927f20a50a8122a0c965230c149e184aeda3ff2853
7
+ data.tar.gz: d93d85055fa6e6763788dc6d8655e33811d7f6fe2ca930f6f373a7c17e4c4b287db81131feac2ea3f43c8c9c46f8346f31801d3167ce97210da9b1fb9d68ad01
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sarvesh Kumar Dwivedi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # RouteSchemer
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/route_schemer.svg)](https://badge.fury.io/rb/route_schemer) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
4
+
5
+ **RouteSchemer** is a Ruby gem designed for Rails applications to streamline schema validation of requests and responses for API endpoints. It leverages `JSONSchemer` for validation against OpenAPI-style JSON schemas. This gem makes it easy to ensure that API payloads conform to predefined structures and simplifies error handling for mismatched data.
6
+
7
+ ---
8
+
9
+ ## 🌟 Why RouteSchemer?
10
+
11
+ As a developer with a background in Python's FastAPI, I noticed a gap in the Rails ecosystem for robust schema validation. FastAPI provides clear, built-in tools for validating and documenting API contracts, and I wanted to bring a similar experience to Rails. RouteSchemer fills this gap by making JSON schema validation seamless and Rails-friendly.
12
+
13
+ ---
14
+
15
+ ## 🚀 Features
16
+
17
+ - Automatically validate requests and responses against JSON schemas.
18
+ - Supports nested controllers and complex schema structures.
19
+ - Generates schema files for controllers using a Rails-like generator.
20
+ - Provides a simple API to access validated and filtered parameters.
21
+ - Custom error handling for schema mismatches.
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
26
+
27
+ Install the gem and add to the application's Gemfile by executing:
28
+
29
+ ```bash
30
+ bundle add route_schemer
31
+ ```
32
+
33
+ If bundler is not being used to manage dependencies, install the gem by executing:
34
+
35
+ ```bash
36
+ gem install route_schemer
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🛠️ Getting Started
42
+
43
+ ### Step 1: Generate a Controller and a RouteSchemer
44
+
45
+ Create a new controller and corresponding RouteSchemer with:
46
+
47
+ ```bash
48
+ rails g controller Foo demo
49
+ rails g route_schemer Foo demo
50
+ ```
51
+
52
+ This will generate:
53
+
54
+ - A `FooController` with an action `demo`
55
+ - A schema file in `app/route_schemers/foo_route_schemer.rb`
56
+
57
+ ### Step 2: Define a Schema
58
+
59
+ Edit the generated `FooRouteSchemer` file to define a schema:
60
+
61
+ ```ruby
62
+ class FooRouteSchemer < ApplicationRouteSchemer
63
+ def self.demo_request_schema
64
+ JSONSchemer.schema({
65
+ type: "object",
66
+ properties: {
67
+ name: { type: "string" },
68
+ age: { type: "integer" }
69
+ },
70
+ required: ["name", "age"]
71
+ })
72
+ end
73
+
74
+ def self.demo_response_schema
75
+ JSONSchemer.schema({
76
+ type: "object",
77
+ properties: {
78
+ success: { type: "boolean" },
79
+ message: { type: "string" }
80
+ },
81
+ required: ["success"]
82
+ })
83
+ end
84
+ end
85
+ ```
86
+
87
+ ### Step 3: Use in the Controller
88
+
89
+ In `FooController`, use the validation helpers provided by the gem:
90
+ Make Sure to include `RouteSchemer` in `ApplicationController`
91
+
92
+ ```ruby
93
+ class FooController < ApplicationController
94
+
95
+ def demo
96
+ @filtered_params = validated_params # auto fetches requests schema
97
+
98
+ # Your controller logic
99
+ response = validated_params(request: false, permit: false) # auto fetches response schema
100
+ render json: response, status: :ok
101
+ end
102
+ end
103
+ ```
104
+
105
+ The `validated_params` method automatically applies the request schema for the current action (`demo_request_schema` in this case).
106
+
107
+ The `validated_params(request: false, permit: false)` validates response and do not permits as we do not need to permit in case of response.
108
+
109
+ ---
110
+
111
+ ## 🔧 Advanced Usage
112
+
113
+ ### Custom Schemas in Methods
114
+
115
+ You can override the default behavior of using `validated_params` with a custom schema:
116
+
117
+ ```ruby
118
+ class FooController < ApplicationController
119
+ def custom_action
120
+ schema = CustomRouteSchemer.some_other_schema
121
+ @filtered_params = validated_params(schema: schema)
122
+ render json: { success: true }
123
+ end
124
+ end
125
+ ```
126
+
127
+ ### Error Handling
128
+
129
+ RouteSchemer raises `RouteSchemer::RequestSchemerError` when validation fails. You can handle this error in your Rails application by rescuing it globally:
130
+
131
+ ```ruby
132
+ class ApplicationController < ActionController::API
133
+ rescue_from RouteSchemer::RequestSchemerError do |e|
134
+ Rails.logger.debug e.details # has all errors
135
+ render json: { error: e.message }, status: :unprocessable_entity
136
+ end
137
+ end
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 🧪 Testing
143
+
144
+ To test a controller action with RouteSchemer, make a request with a valid or invalid payload and ensure that:
145
+
146
+ - A valid payload is processed successfully.
147
+ - An invalid payload triggers the appropriate error response.
148
+
149
+ ---
150
+
151
+ ## 🤝 Contributing
152
+
153
+ Contributions are welcome! To contribute:
154
+
155
+ 1. Fork the repository.
156
+ 2. Create a new branch for your feature/bugfix.
157
+ 3. Submit a pull request with a detailed description of your changes.
158
+
159
+ If you would like to streamline and standardize commit messages, please give a try to [pygitmate](https://github.com/sarvesh4396/pygitmate) also created by me.
160
+ ---
161
+
162
+ ## ⭐ Star the Repository
163
+
164
+ If you find this project helpful, consider starring the repository on GitHub to show your support!
165
+
166
+ [![Star this repo](https://img.shields.io/github/stars/yourusername/route_schemer.svg?style=social)](https://github.com/sarvesh4396/route_schemer)
167
+
168
+ ---
169
+
170
+ ## 📜 License
171
+
172
+ RouteSchemer is open-source software licensed under the [MIT License](./LICENSE).
173
+
174
+ ---
175
+
176
+ ## Code of Conduct
177
+
178
+ Everyone interacting in the RouteSchemer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/sarvesh4396/route_schemer/blob/master/CODE_OF_CONDUCT.md).
179
+
180
+ ---
181
+
182
+ ## 🙏 Acknowledgments
183
+
184
+ - Thanks to the creators of `JSONSchemer` for powering the schema validation.
185
+ - Inspired by Rails' generators and extensible architecture.
186
+
187
+ ## TODO
188
+ - [ ] Parsing of date strings to objects after validating in request.
189
+ - [ ] Add more comprehensive documentation with examples.
190
+ - [ ] Provide detailed guides for common use cases and best practices.
191
+ - [ ] Make controller existence optional, allowing generation even if the controller doesn't exist.
192
+ - [ ] Explore support for `ActiveModel` to enhance schema validation using the Rails ecosystem.
193
+ - [ ] Add support for custom error messages in schema validations.
194
+ - [ ] Set up continuous integration and deployment pipelines.
195
+ - [ ] Enhance test coverage and add more unit and integration tests.
196
+ - [ ] Add auto integration to support swagger generation of present schemers.
197
+ - [ ] Implement strict option as optional for schema validation so that schema validation passes but no errors.
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ # A Rails generator that creates route schema files for controllers.
6
+ # This generator validates the existence of controllers and their methods,
7
+ # then generates both application-wide and controller-specific route schema files.
8
+ #
9
+ # @example Generate schema for UserController with index and show actions
10
+ # rails generate route_schemer User index show
11
+ #
12
+ # @param controller_name [String] The name of the controller to generate schema for (e.g., 'Users' or 'Api::Users')
13
+ # @param methods [Array<String>] List of controller methods/actions to include in the schema
14
+ #
15
+ # @raise [ArgumentError] If the controller doesn't exist or specified methods are not defined
16
+ class RouteSchemerGenerator < Rails::Generators::Base
17
+ source_root File.expand_path("templates", __dir__)
18
+
19
+ argument :controller_name, type: :string
20
+ argument :methods, type: :array, default: []
21
+
22
+ def validate_controller
23
+ # Ensure controller_name is properly formatted (e.g., Foo or Foo::Bar)
24
+ controller_path = File.join("app", "controllers", "#{controller_name.underscore}_controller.rb")
25
+ unless File.exist?(controller_path)
26
+ raise ArgumentError, "Controller #{controller_name} does not exist at #{controller_path}"
27
+ end
28
+
29
+ # Attempt to constantize the controller name
30
+ begin
31
+ @controller_class = "#{controller_name}Controller".constantize
32
+ rescue NameError
33
+ raise ArgumentError, "Controller class #{controller_name} could not be found. Ensure it is defined correctly."
34
+ end
35
+
36
+ # Validate each method in the controller class
37
+ methods.each do |method|
38
+ unless @controller_class.instance_methods.include?(method.to_sym)
39
+ raise ArgumentError, "Method #{method} is not defined in #{controller_name}"
40
+ end
41
+ end
42
+ end
43
+
44
+ def create_route_schemer_file
45
+ # Define the path based on the nested structure of `controller_name`
46
+ schemer_directory = File.join("app", "route_schemers")
47
+
48
+ # Create nested directories if they don't exist
49
+ FileUtils.mkdir_p(schemer_directory) unless Dir.exist?(schemer_directory)
50
+
51
+ # Generate the application route schemer file
52
+ application_schemer_file = File.join("app", "route_schemers", "application_route_schemer.rb")
53
+ unless File.exist?(application_schemer_file)
54
+ template "application_route_schemer_template.rb.tt",
55
+ application_schemer_file
56
+ end
57
+
58
+ # Generate the schemer file always override
59
+ schemer_file = File.join(schemer_directory, "#{controller_name.demodulize.underscore}_route_schemer.rb")
60
+ template "route_schemer_template.rb.tt", schemer_file
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ class ApplicationRouteSchemer
2
+ # write your own custom configuration and formats for schema generation
3
+ # def fetch_schema_object(schema)
4
+ # JSONSchemer.schema(schema)
5
+ # end
6
+ end
@@ -0,0 +1,22 @@
1
+ class <%= controller_name %>RouteSchemer < ApplicationRouteSchemer
2
+ <% methods.each do |method| %>
3
+ def self.<%= method %>_request_schema
4
+ {
5
+ # Example Request JSON schema for <%= method %>
6
+ type: "object",
7
+ required: [],
8
+ properties: {}
9
+ }
10
+ end
11
+
12
+ def self.<%= method %>_response_schema
13
+ {
14
+ # Example Response JSON schema for <%= method %>
15
+ type: "object",
16
+ required: [],
17
+ properties: {}
18
+ }
19
+ end
20
+
21
+ <% end %>
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RouteSchemer
4
+ # Custom error class for schema validation failures in RouteSchemer.
5
+ # This error is raised when request or response parameters fail JSON schema validation.
6
+ class RequestSchemerError < StandardError
7
+ # @return [Array<Hash>] Details of the validation failures
8
+ attr_reader :details
9
+
10
+ # Initialize a new RequestSchemerError
11
+ # @param message [String] The error message
12
+ # @param details [Array<Hash>, nil] Detailed validation errors from JSONSchemer
13
+ def initialize(message, details = nil)
14
+ @details = details
15
+ super(process_error(message))
16
+ end
17
+
18
+ def process_error(message)
19
+ # TODO: format error message
20
+ message
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A module for JSON schema validation in Rails controllers.
4
+ # Provides methods for validating request and response parameters against JSON schemas.
5
+ # This module is automatically included in Rails controllers through the RouteSchemer::Engine.
6
+ #
7
+ # @example Validating request parameters in a controller
8
+ # def create
9
+ # params = validated_params(schema: MyRouteSchemer.create_request_schema)
10
+ # # ...
11
+ # end
12
+ module RouteSchemer
13
+ extend ActiveSupport::Concern
14
+
15
+ def validated_params(schema: nil, params: nil, request: true, permit: true)
16
+ # Default to dynamically determined schema and params if not provided
17
+ schema ||= schema_for_current_action(request)
18
+ raise ArgumentError, "No schema defined for validation" unless schema
19
+
20
+ params ||= self.params
21
+
22
+ data = request ? validate_request(schema, params) : validate_response(schema, params)
23
+ permit ? @permitted_params || permitted_params(schema, data) : data
24
+ end
25
+
26
+ def schema_for_current_action(request)
27
+ # Derive the associated RouteSchemer class (e.g., FooController -> FooRouteSchemer)
28
+ route_schemer_class = "#{controller_path.camelize}RouteSchemer".constantize
29
+ schema_method_name = request ? "#{action_name}_request_schema" : "#{action_name}_response_schema"
30
+ # Look up the schema method on the RouteSchemer class
31
+ return route_schemer_class.public_send(schema_method_name) if route_schemer_class.respond_to?(schema_method_name)
32
+
33
+ nil
34
+ end
35
+
36
+ # Get a JSONSchemer object for the provided schema
37
+ # @param schema [Hash] the JSON schema to validate against
38
+ # @return [JSONSchemer::Schema] the JSONSchemer object
39
+ def fetch_schema_object(schema)
40
+ JSONSchemer.schema(
41
+ schema,
42
+ before_property_validation: proc do |data, property, property_schema, _|
43
+ value = data[property]
44
+ case property_schema["type"]
45
+ when "integer"
46
+ data[property] = value.to_i if value.is_a?(String) && value.match?(/^\d+$/)
47
+ when "number"
48
+ data[property] = value.to_f if value.is_a?(String) && value.match?(/^[-+]?[0-9]*\.?[0-9]+$/)
49
+ end
50
+ end
51
+ )
52
+ end
53
+
54
+ private
55
+
56
+ # Validate the request parameters against the provided schema
57
+ # @param schema [Hash] the JSON schema to validate against
58
+ # @param data [Hash, ActionController::Parameters] the incoming request parameters
59
+ # @return [Hash] the validated and permitted parameters
60
+ def validate_request(schema, data)
61
+ schemer = fetch_schema_object(schema)
62
+ data = permitted_params(schema, data)
63
+ check_for_error(schemer, data)
64
+ @permitted_params = data
65
+
66
+ data # Return validated and permitted params
67
+ end
68
+
69
+ def check_for_error(schemer, data)
70
+ return if schemer.valid?(data)
71
+
72
+ errors = schemer.validate(data)
73
+ error_message = errors.first["error"]
74
+ raise RequestSchemerError.new(error_message, errors)
75
+ end
76
+
77
+ def validate_response(schema, data)
78
+ schemer = fetch_schema_object(schema)
79
+ check_for_error(schemer, data)
80
+ data
81
+ end
82
+
83
+ # Filters and permits parameters based on a given schema.
84
+ # @param schema [Hash] The schema defining the permitted fields.
85
+ # @param params [ActionController::Parameters, Hash] The parameters to be filtered.
86
+ # @return [Hash] The filtered parameters.
87
+ def permitted_params(schema, params)
88
+ data = {}
89
+ if params.is_a?(ActionController::Parameters)
90
+ data = params.permit(*get_permitted_fields(schema)).to_h
91
+ elsif params.is_a?(Hash)
92
+ data = params.select { |key, _| schema[:properties].key?(key.to_sym) }
93
+ end
94
+ data
95
+ end
96
+
97
+ # Get the permitted fields from the schema
98
+ # @param schema [Hash] the JSON schema to extract permitted fields from
99
+ # @return [Array] the list of permitted fields for rails
100
+ def get_permitted_fields(schema)
101
+ properties = schema[:properties] || {}
102
+ properties.map do |key, value|
103
+ case value[:type]
104
+ when "object"
105
+ { key.to_sym => get_permitted_fields(value) }
106
+ when "array"
107
+ value[:items][:type] == "object" ? { key.to_sym => get_permitted_fields(value[:items]) } : { key.to_sym => [] }
108
+ else
109
+ key.to_sym
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RouteSchemer
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json_schemer"
4
+ require "active_support/concern"
5
+ require "route_schemer/route_schemer"
6
+ require "route_schemer/errors/request_schemer_error"
7
+
8
+ # A module for JSON schema validation in Rails controllers.
9
+ # Provides methods for validating request/response parameters against JSON schemas.
10
+ # This module is automatically included in Rails controllers through the Engine.
11
+ module RouteSchemer
12
+ # Rails engine that automatically includes RouteSchemer functionality in Rails controllers.
13
+ # Hooks into the Rails initialization process to include the RouteSchemer module
14
+ # in all ActionController::Base descendants.
15
+ class Engine < ::Rails::Engine
16
+ initializer "route_schemer.include_module" do
17
+ ActiveSupport.on_load(:action_controller_base) do
18
+ include RouteSchemer
19
+ end
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: route_schemer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sarvesh Kumar Dwivedi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json_schemer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '8.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '6.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '8.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: stringio
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 3.1.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 3.1.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubocop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.21'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.21'
89
+ description: Validate your controller routes request and response schemas.
90
+ email:
91
+ - heysarvesh@pm.me
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files:
95
+ - README.md
96
+ - LICENSE
97
+ files:
98
+ - LICENSE
99
+ - README.md
100
+ - lib/generators/route_schemer/route_schemer_generator.rb
101
+ - lib/generators/route_schemer/templates/application_route_schemer_template.rb.tt
102
+ - lib/generators/route_schemer/templates/route_schemer_template.rb.tt
103
+ - lib/route_schemer.rb
104
+ - lib/route_schemer/errors/request_schemer_error.rb
105
+ - lib/route_schemer/route_schemer.rb
106
+ - lib/route_schemer/version.rb
107
+ homepage: https://www.github.com/sarvesh4396/route_schemer
108
+ licenses: []
109
+ metadata:
110
+ homepage_uri: https://www.github.com/sarvesh4396/route_schemer
111
+ source_code_uri: https://www.github.com/sarvesh4396/route_schemer
112
+ changelog_uri: https://www.github.com/sarvesh4396/route_schemer/blob/master/CHANGELOG.md
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '3.0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubygems_version: 3.3.27
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Validate request and response schemas for Rails routes using RouteSchemer
132
+ test_files: []