api-regulator 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: 8474dc3c3898732b6e48a0b2c1722ecc13735e95474b01d9c4223be2cc461653
4
+ data.tar.gz: 541a39193368ff06b3932f869e75d27a50375ae5c2acd772e0276aa2c892bc8a
5
+ SHA512:
6
+ metadata.gz: 67f74a784f20dc965e53a838c6ea8d068242cf77fd7aa7508c6e7e427efd4fef9f29a8242ab737f375b7accc84192551acc40036cfeb9778c1899731510cc102
7
+ data.tar.gz: 732b45b1592042bc7259f82d84b396583a74acb92daac22636d1edddc9f2b41771eea4226459b6709ac109b8ed430a6838ef76a592d2c2742d6ae5dcae3e2b36
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ spec/support/log/**
14
+ spec/tmp
15
+
16
+ api-regulator-*.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.3.6
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.10
7
+ before_install: gem install bundler -v 1.17.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in api-regulator.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,221 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ api-regulator (0.1.0)
5
+ activemodel
6
+ activesupport
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (7.2.2)
12
+ actionpack (= 7.2.2)
13
+ activesupport (= 7.2.2)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ zeitwerk (~> 2.6)
17
+ actionmailbox (7.2.2)
18
+ actionpack (= 7.2.2)
19
+ activejob (= 7.2.2)
20
+ activerecord (= 7.2.2)
21
+ activestorage (= 7.2.2)
22
+ activesupport (= 7.2.2)
23
+ mail (>= 2.8.0)
24
+ actionmailer (7.2.2)
25
+ actionpack (= 7.2.2)
26
+ actionview (= 7.2.2)
27
+ activejob (= 7.2.2)
28
+ activesupport (= 7.2.2)
29
+ mail (>= 2.8.0)
30
+ rails-dom-testing (~> 2.2)
31
+ actionpack (7.2.2)
32
+ actionview (= 7.2.2)
33
+ activesupport (= 7.2.2)
34
+ nokogiri (>= 1.8.5)
35
+ racc
36
+ rack (>= 2.2.4, < 3.2)
37
+ rack-session (>= 1.0.1)
38
+ rack-test (>= 0.6.3)
39
+ rails-dom-testing (~> 2.2)
40
+ rails-html-sanitizer (~> 1.6)
41
+ useragent (~> 0.16)
42
+ actiontext (7.2.2)
43
+ actionpack (= 7.2.2)
44
+ activerecord (= 7.2.2)
45
+ activestorage (= 7.2.2)
46
+ activesupport (= 7.2.2)
47
+ globalid (>= 0.6.0)
48
+ nokogiri (>= 1.8.5)
49
+ actionview (7.2.2)
50
+ activesupport (= 7.2.2)
51
+ builder (~> 3.1)
52
+ erubi (~> 1.11)
53
+ rails-dom-testing (~> 2.2)
54
+ rails-html-sanitizer (~> 1.6)
55
+ activejob (7.2.2)
56
+ activesupport (= 7.2.2)
57
+ globalid (>= 0.3.6)
58
+ activemodel (7.2.2)
59
+ activesupport (= 7.2.2)
60
+ activerecord (7.2.2)
61
+ activemodel (= 7.2.2)
62
+ activesupport (= 7.2.2)
63
+ timeout (>= 0.4.0)
64
+ activestorage (7.2.2)
65
+ actionpack (= 7.2.2)
66
+ activejob (= 7.2.2)
67
+ activerecord (= 7.2.2)
68
+ activesupport (= 7.2.2)
69
+ marcel (~> 1.0)
70
+ activesupport (7.2.2)
71
+ base64
72
+ benchmark (>= 0.3)
73
+ bigdecimal
74
+ concurrent-ruby (~> 1.0, >= 1.3.1)
75
+ connection_pool (>= 2.2.5)
76
+ drb
77
+ i18n (>= 1.6, < 2)
78
+ logger (>= 1.4.2)
79
+ minitest (>= 5.1)
80
+ securerandom (>= 0.3)
81
+ tzinfo (~> 2.0, >= 2.0.5)
82
+ base64 (0.2.0)
83
+ benchmark (0.4.0)
84
+ bigdecimal (3.1.8)
85
+ builder (3.3.0)
86
+ byebug (11.1.3)
87
+ concurrent-ruby (1.3.4)
88
+ connection_pool (2.4.1)
89
+ crass (1.0.6)
90
+ date (3.4.0)
91
+ diff-lcs (1.5.1)
92
+ drb (2.2.1)
93
+ erubi (1.13.0)
94
+ globalid (1.2.1)
95
+ activesupport (>= 6.1)
96
+ i18n (1.14.6)
97
+ concurrent-ruby (~> 1.0)
98
+ io-console (0.7.2)
99
+ irb (1.14.1)
100
+ rdoc (>= 4.0.0)
101
+ reline (>= 0.4.2)
102
+ logger (1.6.1)
103
+ loofah (2.23.1)
104
+ crass (~> 1.0.2)
105
+ nokogiri (>= 1.12.0)
106
+ mail (2.8.1)
107
+ mini_mime (>= 0.1.1)
108
+ net-imap
109
+ net-pop
110
+ net-smtp
111
+ marcel (1.0.4)
112
+ mini_mime (1.1.5)
113
+ mini_portile2 (2.8.8)
114
+ minitest (5.25.2)
115
+ net-imap (0.5.1)
116
+ date
117
+ net-protocol
118
+ net-pop (0.1.2)
119
+ net-protocol
120
+ net-protocol (0.2.2)
121
+ timeout
122
+ net-smtp (0.5.0)
123
+ net-protocol
124
+ nio4r (2.7.4)
125
+ nokogiri (1.16.8)
126
+ mini_portile2 (~> 2.8.2)
127
+ racc (~> 1.4)
128
+ nokogiri (1.16.8-arm64-darwin)
129
+ racc (~> 1.4)
130
+ psych (5.2.0)
131
+ stringio
132
+ racc (1.8.1)
133
+ rack (3.1.8)
134
+ rack-session (2.0.0)
135
+ rack (>= 3.0.0)
136
+ rack-test (2.1.0)
137
+ rack (>= 1.3)
138
+ rackup (2.2.1)
139
+ rack (>= 3)
140
+ rails (7.2.2)
141
+ actioncable (= 7.2.2)
142
+ actionmailbox (= 7.2.2)
143
+ actionmailer (= 7.2.2)
144
+ actionpack (= 7.2.2)
145
+ actiontext (= 7.2.2)
146
+ actionview (= 7.2.2)
147
+ activejob (= 7.2.2)
148
+ activemodel (= 7.2.2)
149
+ activerecord (= 7.2.2)
150
+ activestorage (= 7.2.2)
151
+ activesupport (= 7.2.2)
152
+ bundler (>= 1.15.0)
153
+ railties (= 7.2.2)
154
+ rails-dom-testing (2.2.0)
155
+ activesupport (>= 5.0.0)
156
+ minitest
157
+ nokogiri (>= 1.6)
158
+ rails-html-sanitizer (1.6.1)
159
+ loofah (~> 2.21)
160
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
161
+ railties (7.2.2)
162
+ actionpack (= 7.2.2)
163
+ activesupport (= 7.2.2)
164
+ irb (~> 1.13)
165
+ rackup (>= 1.0.0)
166
+ rake (>= 12.2)
167
+ thor (~> 1.0, >= 1.2.2)
168
+ zeitwerk (~> 2.6)
169
+ rake (13.2.1)
170
+ rdoc (6.8.1)
171
+ psych (>= 4.0.0)
172
+ reline (0.5.11)
173
+ io-console (~> 0.5)
174
+ rspec (3.13.0)
175
+ rspec-core (~> 3.13.0)
176
+ rspec-expectations (~> 3.13.0)
177
+ rspec-mocks (~> 3.13.0)
178
+ rspec-core (3.13.2)
179
+ rspec-support (~> 3.13.0)
180
+ rspec-expectations (3.13.3)
181
+ diff-lcs (>= 1.2.0, < 2.0)
182
+ rspec-support (~> 3.13.0)
183
+ rspec-mocks (3.13.2)
184
+ diff-lcs (>= 1.2.0, < 2.0)
185
+ rspec-support (~> 3.13.0)
186
+ rspec-rails (5.1.2)
187
+ actionpack (>= 5.2)
188
+ activesupport (>= 5.2)
189
+ railties (>= 5.2)
190
+ rspec-core (~> 3.10)
191
+ rspec-expectations (~> 3.10)
192
+ rspec-mocks (~> 3.10)
193
+ rspec-support (~> 3.10)
194
+ rspec-support (3.13.1)
195
+ securerandom (0.3.2)
196
+ stringio (3.1.2)
197
+ thor (1.3.2)
198
+ timeout (0.4.2)
199
+ tzinfo (2.0.6)
200
+ concurrent-ruby (~> 1.0)
201
+ useragent (0.16.10)
202
+ websocket-driver (0.7.6)
203
+ websocket-extensions (>= 0.1.0)
204
+ websocket-extensions (0.1.5)
205
+ zeitwerk (2.7.1)
206
+
207
+ PLATFORMS
208
+ arm64-darwin-23
209
+ ruby
210
+
211
+ DEPENDENCIES
212
+ api-regulator!
213
+ bundler (~> 2.5)
214
+ byebug (= 11.1.3)
215
+ rails (~> 7.0)
216
+ rake (>= 12.3)
217
+ rspec (~> 3.0)
218
+ rspec-rails (~> 5.0)
219
+
220
+ BUNDLED WITH
221
+ 2.5.23
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Geoff Massanek
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # ApiRegulator
2
+
3
+ ApiRegulator is a Ruby gem designed to **document** and **validate APIs** in Rails applications. It provides a clean DSL for defining API endpoints, parameter validations, and response schemas directly in your Rails controllers, while also generating OpenAPI 3.1.0-compliant documentation for tools like Swagger and ReadMe.
4
+
5
+ ApiRegulator relies on **Active Model validations** for parameter validation, making it familiar and intuitive for Rails developers.
6
+
7
+ ## Features
8
+
9
+ - **API Documentation DSL**:
10
+ Define API endpoints, request parameters, and response schemas in an intuitive, Rails-friendly DSL.
11
+
12
+ - **Dynamic Validation**:
13
+ Automatically validate incoming requests against the defined parameters using **Active Model validations**, reducing boilerplate code.
14
+
15
+ - **OpenAPI Documentation**:
16
+ Generate fully compliant OpenAPI 3.1.0 JSON files, ready for use with documentation tools like Swagger or ReadMe.
17
+
18
+ - **Reusability**:
19
+ Share common response schemas across multiple endpoints for DRY definitions.
20
+
21
+ ## ToDo
22
+ - [ ] More tests
23
+ - [ ] Invalid Configurations (errors for invalid types)
24
+ - [ ] Empty Shared Schemas
25
+ - [ ] Custom Length and Numericality Options
26
+ - [ ] Publish to rubygems
27
+ - [ ] See if we're missing any other OpenAPI directives we could use
28
+ - [ ] nullable params
29
+ - [ ] Handling of extra undocumented params
30
+ - [ ] Set up CI / CD
31
+
32
+ ## Installation
33
+
34
+ Add ApiRegulator to your Gemfile:
35
+
36
+ ```ruby
37
+ gem 'api_regulator'
38
+ ```
39
+
40
+ Run `bundle install` to install the gem.
41
+
42
+
43
+ ## Setup
44
+
45
+ 1. **Create an Initializer**:
46
+
47
+ Add the following to `config/initializers/api_regulator.rb`:
48
+
49
+ ```ruby
50
+ ApiRegulator.configure do |config|
51
+ config.base_controller = "Api::ApplicationController" # Set your base API controller
52
+ config.api_base_url = "/api/v1" # Set a common base path for your API endpoints
53
+ config.docs_path = Rails.root.join("doc", "openapi.json").to_s # Path for OpenAPI JSON file
54
+ config.app_name = "My API" # shows in docs
55
+ config.rdme_api_id = ENV["RDME_API_ID"] # Optional: ReadMe API ID for schema uploads
56
+ config.servers = [
57
+ { url: "https://stg.example.com", description: "Staging", "x-default": true },
58
+ { url: "https://example.com", description: "Production" }
59
+ ]
60
+ end
61
+ ```
62
+
63
+ 2. **Include the DSL in Your Base Controller**:
64
+
65
+ Include the DSL and validation methods in your base API controller:
66
+
67
+ ```ruby
68
+ class Api::ApplicationController < ActionController::API
69
+ include ApiRegulator::DSL
70
+ include ApiRegulator::ControllerMixin
71
+ end
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ **Defining Endpoints**
77
+
78
+ Use the DSL in your controllers to define API endpoints, request parameters, and response schemas.
79
+
80
+ ```ruby
81
+ class Api::V1::CustomersController < Api::ApplicationController
82
+ api self, :create, "Enroll a customer" do
83
+ param :customer, presence: true do
84
+ param :first_name, :string, presence: true
85
+ param :last_name, :string, presence: true
86
+ param :email, :string, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
87
+ param :ssn, :string, presence: true, length: { minimum: 9, maximum: 9 }
88
+ end
89
+
90
+ response 200, "Customer successfully enrolled" do
91
+ param :customer do
92
+ param :id, :string, desc: "Customer ID"
93
+ param :email, :string, desc: "Customer email"
94
+ end
95
+ end
96
+
97
+ response 422, ref: :validation_errors
98
+ end
99
+
100
+ def create
101
+ validate_params! # Validate request params against the DSL definition
102
+
103
+ customer = Customer.create!(api_params[:customer]) # Use dynamically generated params
104
+ render json: customer, status: :ok
105
+ end
106
+ end
107
+ ```
108
+
109
+ ## Shared Schemas
110
+
111
+ Define reusable schemas for common responses in your initializer:
112
+
113
+ ```ruby
114
+ ApiRegulator.shared_schema :validation_errors, "Validation error response" do
115
+ param :errors, :array, desc: "Array of validation errors", items_type: :string
116
+ end
117
+ ```
118
+
119
+ Reference the shared schema in your responses:
120
+ ```ruby
121
+ response 422, ref: :validation_errors
122
+ end
123
+ ```
124
+
125
+ ## Generating OpenAPI Documentation
126
+
127
+ Generate OpenAPI documentation using the provided Rake tasks:
128
+
129
+
130
+ 1. **Generate the Schema:**
131
+ ```bash
132
+ rake api_docs:generate
133
+ ```
134
+
135
+ 2. **Upload to ReadMe (Optional)**:
136
+ ```bash
137
+ rake api_docs:upload
138
+ ```
139
+ This uploads the OpenAPI file to ReadMe. Ensure you’ve configured the RDME_API_KEY and optional RDME_API_ID.
140
+
141
+ 3. **Publish Both**:
142
+ ```bash
143
+ rake api_docs:publish
144
+ ```
145
+
146
+ ## Contributing
147
+ 1. Fork the repository.
148
+ 2. Create your feature branch (git checkout -b feature/new-feature).
149
+ 3. Commit your changes (git commit -am 'Add some feature').
150
+ 4. Push to the branch (git push origin feature/new-feature).
151
+ 5. Open a pull request.
152
+
153
+ ## License
154
+ This gem is available as open-source software under the [MIT License](https://mit-license.org/).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,48 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "api_regulator/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "api-regulator"
8
+ spec.version = ApiRegulator::VERSION
9
+ spec.authors = ["Geoff Massanek"]
10
+ spec.email = ["geoff@stellarfi.com"]
11
+
12
+ spec.summary = %q{Define, document, and validate your Rails APIs}
13
+ spec.description = %q{Define your Rails APIs with a clean, familiar DSL. Validate them with ActiveModel-like validations. Generate OpenAPI documentation.}
14
+ spec.homepage = "https://github.com/Stellarcred/stellar-gears"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
21
+
22
+ spec.metadata["homepage_uri"] = spec.homepage
23
+ spec.metadata["source_code_uri"] = "https://github.com/Stellarcred/stellar-gears"
24
+ spec.metadata["changelog_uri"] = "https://github.com/Stellarcred/stellar-gears"
25
+ else
26
+ raise "RubyGems 2.0 or newer is required to protect against " \
27
+ "public gem pushes."
28
+ end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = "exe"
36
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ["lib"]
38
+
39
+ spec.add_runtime_dependency "activesupport"
40
+ spec.add_runtime_dependency "activemodel"
41
+
42
+ spec.add_development_dependency "bundler", "~> 2.5"
43
+ spec.add_development_dependency "rake", ">= 12.3"
44
+ spec.add_development_dependency "rails", "~> 7.0"
45
+ spec.add_development_dependency "rspec", "~> 3.0"
46
+ spec.add_development_dependency "rspec-rails", "~> 5.0"
47
+ spec.add_development_dependency "byebug", "11.1.3"
48
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "api/regulator"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,35 @@
1
+ require_relative 'api_regulator/api'
2
+ require_relative 'api_regulator/configuration'
3
+ require_relative 'api_regulator/controller_mixin'
4
+ require_relative 'api_regulator/dsl'
5
+ require_relative 'api_regulator/formats'
6
+ require_relative 'api_regulator/open_api_generator'
7
+ require_relative 'api_regulator/param'
8
+ require_relative 'api_regulator/shared_schema'
9
+ require_relative 'api_regulator/validation_error'
10
+ require_relative 'api_regulator/validator'
11
+ require_relative 'api_regulator/version'
12
+
13
+ # Load tasks if Rails is present
14
+ if defined?(Rake)
15
+ load 'tasks/api_regulator_tasks.rake'
16
+ end
17
+
18
+ module ApiRegulator
19
+ class Error < StandardError; end
20
+
21
+ class << self
22
+ attr_accessor :configuration
23
+
24
+ def configure
25
+ self.configuration ||= Configuration.new
26
+ yield(configuration)
27
+ end
28
+
29
+ def prepare_validators
30
+ Rails.application.eager_load! # Ensure all controllers and API definitions are loaded
31
+ api_definitions = ApiRegulator.configuration.base_controller_klass.descendants.flat_map(&:api_definitions)
32
+ ApiRegulator::Validator.build_all(api_definitions)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,82 @@
1
+ module ApiRegulator
2
+ class Api
3
+ attr_reader :controller_class, :controller_path, :controller_name, :action_name, :description, :params, :responses
4
+
5
+ def initialize(controller_class, action_name, description, &block)
6
+ @controller_class = controller_class
7
+ @controller_name = controller_class.name
8
+ @controller_path = controller_class.controller_path
9
+ @action_name = action_name.to_s
10
+ @description = description
11
+
12
+ @params = []
13
+ @responses = {}
14
+
15
+ instance_eval(&block) if block_given?
16
+ end
17
+
18
+ def param(name, type = nil, item_type: nil, desc: "", location: :body, **options, &block)
19
+ param = Param.new(name, type, item_type: item_type, desc: desc, location: location, **options, &block)
20
+ @params << param
21
+ end
22
+
23
+ def ref(ref_name)
24
+ shared_schema = ApiRegulator.shared_schemas[ref_name]
25
+ raise "Shared schema #{ref_name} not found" unless shared_schema
26
+
27
+ shared_schema.params.each do |shared_param|
28
+ @params << shared_param
29
+ end
30
+ end
31
+
32
+ def response(status_code, description_or_options, &block)
33
+ if description_or_options.is_a?(Hash) && description_or_options[:ref]
34
+ # Reference to a shared schema
35
+ @responses[status_code] = Param.new(:root, :object, ref: description_or_options[:ref], &block)
36
+ else
37
+ # Inline schema definition
38
+ schema = Param.new(:root, :object, desc: description_or_options, &block)
39
+ @responses[status_code] = schema
40
+ end
41
+ end
42
+
43
+ def path
44
+ rails_route.path.spec.to_s
45
+ .sub("(.:format)", "") # Remove optional format
46
+ .gsub(/:([\w_]+)/, '{\1}') # Replace `:param` with `{param}`
47
+ end
48
+
49
+ def http_method
50
+ rails_route.verb&.downcase
51
+ end
52
+
53
+ def rails_route
54
+ route = Rails.application.routes.routes.find do |r|
55
+ r.defaults[:controller] == controller_path &&
56
+ r.defaults[:action] == action_name
57
+ end
58
+
59
+ raise "HTTP method not found for #{controller_name}##{action_name}" unless route
60
+
61
+ route
62
+ end
63
+
64
+ def operation_id
65
+ "#{controller_path.gsub("/", "-")}-#{action_name}"
66
+ end
67
+
68
+ def tags
69
+ [
70
+ controller_name
71
+ .demodulize
72
+ .sub("Controller", "")
73
+ .underscore
74
+ .humanize
75
+ ]
76
+ end
77
+
78
+ def allows_body?
79
+ http_method != "get"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,18 @@
1
+ module ApiRegulator
2
+ class Configuration
3
+ attr_accessor :base_controller, :api_base_url, :app_name, :docs_path, :rdme_api_id, :servers
4
+
5
+ def initialize
6
+ # Set default values
7
+ @base_controller = "ApplicationController"
8
+ @api_base_url = "api/v1"
9
+ @app_name = "API Documentation"
10
+ @docs_path = "openapi.json"
11
+ @servers = []
12
+ end
13
+
14
+ def base_controller_klass
15
+ ApiRegulator.configuration.base_controller.constantize
16
+ end
17
+ end
18
+ end