api-regulator 0.1.1 → 0.1.2

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: 88bc51a665a125169fea48c149623cfc72df75a4996685ea847ef84c83819aec
4
- data.tar.gz: 1d61290605b37dd3c5a2b3b48d52490bbe5d1b993713f6d4386cfb7aedda3f21
3
+ metadata.gz: 805a7ee5772352ec9d9f1e8bea5f6f79ef5dd67c170bfb3ca62898a2685a0067
4
+ data.tar.gz: 75d36c102ed4f9494cfb8f97be7cca09de8206006fb1ca28352734f15ecc29d1
5
5
  SHA512:
6
- metadata.gz: 7a3b2f318a78aa7c171faf82b7b24e1ede15a7a7d2a447f308f56b8aafe7c32da3ae611ed0303ac79013cef7355c82988c02dc5ed24cd9928bd9bb17fcef9c84
7
- data.tar.gz: 82f9714a67fb41d91b65086e2fadd379cf04ea1516e93d853730a4c4be7bc663730cf8bdece2338c9931c3eb66fa8944cc2d436479f1d26cdfaa81645309ca87
6
+ metadata.gz: 45f235550878457b9af59dc1f3d4d2b70ac8afe581dfc35d9f5a13a37da67eb17ef9f6e4da1d877352eca27229847367909645f66d20cdaa807d9c52f133c894
7
+ data.tar.gz: a67c9b219a20a6e9dffd99fa33f285222452621b99c7304ffd3e7366f86fb8046505857c27047a86161bf3232cf07b81e35a75a7375fe7bace8a0708982ba9c1
data/.gitignore CHANGED
@@ -14,3 +14,4 @@ spec/support/log/**
14
14
  spec/tmp
15
15
 
16
16
  api-regulator-*.gem
17
+ .byebug_history
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- api-regulator (0.1.0)
4
+ api-regulator (0.1.2)
5
5
  activemodel
6
6
  activesupport
7
7
 
data/README.md CHANGED
@@ -48,9 +48,8 @@ Run `bundle install` to install the gem.
48
48
 
49
49
  ```ruby
50
50
  ApiRegulator.configure do |config|
51
- config.base_controller = "Api::ApplicationController" # Set your base API controller
52
51
  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
52
+ config.docs_path = Rails.root.join("doc").to_s # Path for folder for docs
54
53
  config.app_name = "My API" # shows in docs
55
54
  config.rdme_api_id = ENV["RDME_API_ID"] # Optional: ReadMe API ID for schema uploads
56
55
  config.servers = [
@@ -111,7 +110,7 @@ end
111
110
  Define reusable schemas for common responses in your initializer:
112
111
 
113
112
  ```ruby
114
- ApiRegulator.shared_schema :validation_errors, "Validation error response" do
113
+ ApiRegulator.register_shared_schema :validation_errors, "Validation error response" do
115
114
  param :errors, :array, desc: "Array of validation errors", items_type: :string
116
115
  end
117
116
  ```
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "api/regulator"
4
+ require "api-regulator"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
data/lib/api-regulator.rb CHANGED
@@ -5,10 +5,12 @@ require_relative 'api_regulator/dsl'
5
5
  require_relative 'api_regulator/formats'
6
6
  require_relative 'api_regulator/open_api_generator'
7
7
  require_relative 'api_regulator/param'
8
+ require_relative 'api_regulator/security'
8
9
  require_relative 'api_regulator/shared_schema'
9
10
  require_relative 'api_regulator/validation_error'
10
11
  require_relative 'api_regulator/validator'
11
12
  require_relative 'api_regulator/version'
13
+ require_relative 'api_regulator/webhook'
12
14
 
13
15
  # Load tasks if Rails is present
14
16
  if defined?(Rake)
@@ -28,8 +30,8 @@ module ApiRegulator
28
30
 
29
31
  def prepare_validators
30
32
  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
+
34
+ ApiRegulator::Validator.build_all(ApiRegulator.api_definitions)
33
35
  end
34
36
  end
35
37
  end
@@ -1,13 +1,14 @@
1
1
  module ApiRegulator
2
2
  class Api
3
- attr_reader :controller_class, :controller_path, :controller_name, :action_name, :description, :params, :responses
3
+ attr_reader :controller_class, :controller_path, :controller_name, :action_name, :description, :title, :params, :responses
4
4
 
5
- def initialize(controller_class, action_name, description, &block)
5
+ def initialize(controller_class, action_name, desc: nil, title: nil, &block)
6
6
  @controller_class = controller_class
7
7
  @controller_name = controller_class.name
8
8
  @controller_path = controller_class.controller_path
9
9
  @action_name = action_name.to_s
10
- @description = description
10
+ @description = desc
11
+ @title = title
11
12
 
12
13
  @params = []
13
14
  @responses = {}
@@ -20,11 +21,20 @@ module ApiRegulator
20
21
  @params << param
21
22
  end
22
23
 
23
- def ref(ref_name)
24
- shared_schema = ApiRegulator.shared_schemas[ref_name]
24
+ def ref(ref_name, except: [], only: [])
25
+ shared_schema = ApiRegulator.shared_schema(ref_name)
25
26
  raise "Shared schema #{ref_name} not found" unless shared_schema
26
27
 
27
- shared_schema.params.each do |shared_param|
28
+ # Filter parameters based on `only` or `except` options
29
+ filtered_params = shared_schema.params
30
+
31
+ if only.any?
32
+ filtered_params = filtered_params.select { |param| only.include?(param.name) }
33
+ elsif except.any?
34
+ filtered_params = filtered_params.reject { |param| except.include?(param.name) }
35
+ end
36
+
37
+ filtered_params.each do |shared_param|
28
38
  @params << shared_param
29
39
  end
30
40
  end
@@ -79,4 +89,14 @@ module ApiRegulator
79
89
  http_method != "get"
80
90
  end
81
91
  end
92
+
93
+ class << self
94
+ def api_definitions
95
+ @api_definitions ||= []
96
+ end
97
+
98
+ def reset_api_definitions
99
+ @api_definitions = []
100
+ end
101
+ end
82
102
  end
@@ -1,18 +1,13 @@
1
1
  module ApiRegulator
2
2
  class Configuration
3
- attr_accessor :base_controller, :api_base_url, :app_name, :docs_path, :rdme_api_id, :servers
3
+ attr_accessor :api_base_url, :app_name, :docs_path, :rdme_api_id, :servers
4
4
 
5
5
  def initialize
6
6
  # Set default values
7
- @base_controller = "ApplicationController"
8
7
  @api_base_url = "api/v1"
9
8
  @app_name = "API Documentation"
10
- @docs_path = "openapi.json"
9
+ @docs_path = "doc"
11
10
  @servers = []
12
11
  end
13
-
14
- def base_controller_klass
15
- ApiRegulator.configuration.base_controller.constantize
16
- end
17
12
  end
18
13
  end
@@ -9,17 +9,24 @@ module ApiRegulator
9
9
  end
10
10
 
11
11
  module ClassMethods
12
- def api(controller_class, action, description, &block)
12
+ def api(controller_class, action, desc: nil, title: nil, &block)
13
13
  @api_definitions ||= []
14
14
 
15
15
  api_definition = Api.new(
16
16
  controller_class,
17
17
  action.to_s,
18
- description,
18
+ desc: desc,
19
+ title: title,
19
20
  &block
20
21
  )
21
22
 
22
23
  @api_definitions << api_definition
24
+ ApiRegulator.api_definitions << api_definition
25
+ end
26
+
27
+ def webhook(event_name, desc: nil, title: nil, tags: [], &block)
28
+ webhook = Webhook.new(event_name, desc: desc, title: title, tags: tags, &block)
29
+ ApiRegulator.webhook_definitions << webhook
23
30
  end
24
31
 
25
32
  def api_definitions
@@ -16,13 +16,15 @@ module ApiRegulator
16
16
 
17
17
  add_components(schema)
18
18
  add_security(schema)
19
+ add_webhooks(schema)
19
20
 
20
21
  api_definitions.each do |api|
21
22
  add_api_to_schema(schema, api)
22
23
  end
23
24
 
24
- File.write(ApiRegulator.configuration.docs_path, JSON.pretty_generate(schema))
25
- puts "OpenAPI schema generated: #{ApiRegulator.configuration.docs_path}"
25
+ schema_path = "#{ApiRegulator.configuration.docs_path}/openapi.json"
26
+ File.write(schema_path, JSON.pretty_generate(schema))
27
+ puts "OpenAPI schema generated: #{schema_path}"
26
28
  end
27
29
 
28
30
  private
@@ -30,13 +32,13 @@ module ApiRegulator
30
32
  def self.add_api_to_schema(schema, api)
31
33
  schema[:paths][api.path] ||= {}
32
34
  data = {
33
- summary: api.description,
34
- description: api.description,
35
+ summary: api.title,
36
+ description: api.description.presence || api.title,
35
37
  operationId: api.operation_id,
36
38
  tags: api.tags,
37
39
  parameters: generate_parameters(api),
38
40
  responses: generate_responses(api)
39
- }
41
+ }.compact
40
42
 
41
43
  data[:requestBody] = generate_request_body(api) if api.allows_body?
42
44
  data.delete(:requestBody) if data[:requestBody].blank?
@@ -113,16 +115,20 @@ module ApiRegulator
113
115
  def self.generate_param_schema(param)
114
116
  schema = {}
115
117
 
118
+ schema[:description] = param.desc if param.desc.present?
119
+
116
120
  if param.parameter?
117
121
  schema[:in] = param.location
118
122
  schema[:schema] = { type: param.type.to_s.downcase }
123
+ generate_param_schema_details(param, schema[:schema])
119
124
  else
120
125
  schema[:type] = param.type.to_s.downcase
126
+ generate_param_schema_details(param, schema)
121
127
  end
128
+ schema
129
+ end
122
130
 
123
- schema[:description] = param.desc if param.desc.present?
124
-
125
-
131
+ def self.generate_param_schema_details(param, schema)
126
132
  # Add length constraints
127
133
  if param.options[:length]
128
134
  schema[:minLength] = param.options[:length][:minimum] if param.options[:length][:minimum]
@@ -142,12 +148,12 @@ module ApiRegulator
142
148
  end
143
149
  end
144
150
 
145
- if param.options[:numericality]
146
- schema[:type] = param.options[:only_integer] ? 'integer' : 'number'
147
- schema[:minimum] = param.options[:greater_than_or_equal_to] if param.options[:greater_than_or_equal_to]
148
- schema[:maximum] = param.options[:less_than_or_equal_to] if param.options[:less_than_or_equal_to]
149
- schema[:exclusiveMinimum] = param.options[:greater_than] if param.options[:greater_than]
150
- schema[:exclusiveMaximum] = param.options[:less_than] if param.options[:less_than]
151
+ if numericality = param.options[:numericality]
152
+ schema[:type] = numericality[:only_integer] || schema[:type] == "integer" ? 'integer' : 'number'
153
+ schema[:minimum] = numericality[:greater_than_or_equal_to] if numericality[:greater_than_or_equal_to]
154
+ schema[:maximum] = numericality[:less_than_or_equal_to] if numericality[:less_than_or_equal_to]
155
+ schema[:exclusiveMinimum] = numericality[:greater_than] if numericality[:greater_than]
156
+ schema[:exclusiveMaximum] = numericality[:less_than] if numericality[:less_than]
151
157
  end
152
158
 
153
159
  if param.options[:inclusion]
@@ -160,13 +166,12 @@ module ApiRegulator
160
166
 
161
167
  schema[:nullable] = true if param.options[:allow_nil]
162
168
 
163
- schema
164
169
  end
165
170
 
166
171
  def self.generate_responses(api)
167
172
  api.responses.each_with_object({}) do |(status_code, schema), responses|
168
173
  if schema.options[:ref]
169
- shared_schema = ApiRegulator.shared_schemas[schema.options[:ref]]
174
+ shared_schema = ApiRegulator.shared_schema(schema.options[:ref])
170
175
  raise "Shared schema not found for ref: #{schema.options[:ref]}" unless shared_schema
171
176
 
172
177
  responses[status_code.to_s] = {
@@ -177,6 +182,10 @@ module ApiRegulator
177
182
  }
178
183
  }
179
184
  }.compact
185
+ elsif schema.children.empty?
186
+ responses[status_code.to_s] = {
187
+ description: schema.desc.presence
188
+ }
180
189
  else
181
190
  responses[status_code.to_s] = {
182
191
  description: schema.desc.presence,
@@ -195,6 +204,31 @@ module ApiRegulator
195
204
  add_security_schemes(schema)
196
205
  end
197
206
 
207
+ def self.add_webhooks(schema)
208
+ return if ApiRegulator.webhook_definitions.empty?
209
+
210
+ schema[:webhooks] ||= {}
211
+ ApiRegulator.webhook_definitions.each do |webhook|
212
+ schema[:webhooks][webhook.event_name] = {
213
+ post: {
214
+ summary: webhook.title,
215
+ description: webhook.description.presence || webhook.title,
216
+ tags: webhook.tags,
217
+ requestBody: {
218
+ required: true,
219
+ content: {
220
+ 'application/json' => {
221
+ schema: expand_nested_params(webhook.params),
222
+ examples: webhook.examples || {}
223
+ }
224
+ }
225
+ },
226
+ responses: generate_responses(webhook)
227
+ }.compact
228
+ }
229
+ end
230
+ end
231
+
198
232
  def self.add_shared_schemas(schema)
199
233
  return unless ApiRegulator.shared_schemas.present?
200
234
 
@@ -19,11 +19,20 @@ module ApiRegulator
19
19
  @children << child
20
20
  end
21
21
 
22
- def ref(ref_name)
23
- shared_schema = ApiRegulator.shared_schemas[ref_name]
22
+ def ref(ref_name, except: [], only: [])
23
+ shared_schema = ApiRegulator.shared_schema(ref_name)
24
24
  raise "Shared schema #{ref_name} not found" unless shared_schema
25
25
 
26
- shared_schema.params.each do |shared_param|
26
+ # Filter parameters based on `only` or `except` options
27
+ filtered_params = shared_schema.params
28
+
29
+ if only.any?
30
+ filtered_params = filtered_params.select { |param| only.include?(param.name) }
31
+ elsif except.any?
32
+ filtered_params = filtered_params.reject { |param| except.include?(param.name) }
33
+ end
34
+
35
+ filtered_params.each do |shared_param|
27
36
  @children << shared_param
28
37
  end
29
38
  end
@@ -0,0 +1,13 @@
1
+ module ApiRegulator
2
+ class << self
3
+ attr_accessor :security
4
+
5
+ def security_schemes
6
+ @security_schemes ||= {}
7
+ end
8
+
9
+ def security_schemes=(scheme)
10
+ @security_schemes = scheme
11
+ end
12
+ end
13
+ end
@@ -15,23 +15,32 @@ module ApiRegulator
15
15
  end
16
16
  end
17
17
 
18
+ @shared_schemas = {}
19
+ @shared_schema_registry = {}
20
+
18
21
  class << self
19
- attr_accessor :security
22
+ attr_accessor :shared_schema_registry
20
23
 
21
24
  def shared_schemas
22
- @shared_schemas ||= {}
23
- end
25
+ shared_schema_registry.each do |name, (description, block)|
26
+ @shared_schemas[name] = SharedSchema.new(name, description, &block)
27
+ end
24
28
 
25
- def security_schemes
26
- @security_schemes ||= {}
29
+ @shared_schemas
27
30
  end
28
31
 
29
- def shared_schema(name, description, &block)
30
- shared_schemas[name] = SharedSchema.new(name, description, &block)
32
+ def shared_schema(name)
33
+ if shared_schema_registry[name]
34
+ description, block = shared_schema_registry.delete(name)
35
+
36
+ @shared_schemas[name] = SharedSchema.new(name, description, &block)
37
+ end
38
+
39
+ @shared_schemas[name]
31
40
  end
32
41
 
33
- def security_schemes=(scheme)
34
- @security_schemes = scheme
42
+ def register_shared_schema(name, description, &block)
43
+ shared_schema_registry[name] = [description, block]
35
44
  end
36
45
  end
37
46
  end
@@ -232,6 +232,10 @@ module ApiRegulator
232
232
  end
233
233
  end
234
234
 
235
+ def self.reset_validators
236
+ @validators = {}
237
+ end
238
+
235
239
  def initialize(attributes = {})
236
240
  @raw_attributes = attributes.deep_symbolize_keys
237
241
  allowed_attributes = attributes.slice(*self.class.defined_attributes.map(&:to_sym))
@@ -239,8 +243,3 @@ module ApiRegulator
239
243
  end
240
244
  end
241
245
  end
242
-
243
- class FooValidator
244
- include ActiveModel::Model
245
- include ActiveModel::Attributes
246
- end
@@ -1,3 +1,3 @@
1
1
  module ApiRegulator
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -0,0 +1,59 @@
1
+ module ApiRegulator
2
+ class Webhook
3
+ attr_reader :event_name, :description, :params, :responses, :examples, :tags, :title
4
+
5
+ def initialize(event_name, desc: nil, title: nil, tags: [], &block)
6
+ @event_name = event_name
7
+ @description = desc
8
+ @title = title
9
+ @tags = tags
10
+ @params = []
11
+ @responses = {}
12
+
13
+ instance_eval(&block) if block_given?
14
+ end
15
+
16
+ def param(name, type = nil, item_type: nil, desc: "", location: :body, **options, &block)
17
+ param = Param.new(name, type, item_type: item_type, desc: desc, location: location, **options, &block)
18
+ @params << param
19
+ end
20
+
21
+ def ref(ref_name, except: [], only: [])
22
+ shared_schema = ApiRegulator.shared_schema(ref_name)
23
+ raise "Shared schema #{ref_name} not found" unless shared_schema
24
+
25
+ # Filter parameters based on `only` or `except` options
26
+ filtered_params = shared_schema.params
27
+
28
+ if only.any?
29
+ filtered_params = filtered_params.select { |param| only.include?(param.name) }
30
+ elsif except.any?
31
+ filtered_params = filtered_params.reject { |param| except.include?(param.name) }
32
+ end
33
+
34
+ filtered_params.each do |shared_param|
35
+ @params << shared_param
36
+ end
37
+ end
38
+
39
+ def response(status_code, description, &block)
40
+ @responses[status_code] = Param.new(:root, :object, desc: description, &block)
41
+ end
42
+
43
+ def example(name, value, default: false)
44
+ @examples ||= {}
45
+ @examples[name] = { summary: "#{name} Example", value: value }
46
+ @default_example = value if default
47
+ end
48
+ end
49
+
50
+ class << self
51
+ def webhook_definitions
52
+ @webhook_definitions ||= []
53
+ end
54
+
55
+ def reset_webhook_definitions
56
+ @webhook_definitions = []
57
+ end
58
+ end
59
+ end
@@ -1,10 +1,11 @@
1
+ require 'yaml'
2
+
1
3
  namespace :api_docs do
2
4
  desc 'Generate OpenAPI schema'
3
5
  task generate: :environment do
4
- Rails.application.eager_load!
6
+ Rails.application.eager_load! # Ensure all controllers and API definitions are loaded
5
7
 
6
- api_definitions = ApiRegulator.configuration.base_controller_klass.descendants.flat_map(&:api_definitions)
7
- ApiRegulator::OpenApiGenerator.generate(api_definitions)
8
+ ApiRegulator::OpenApiGenerator.generate(ApiRegulator.api_definitions)
8
9
  end
9
10
 
10
11
  desc "Upload OpenAPI schema to ReadMe"
@@ -16,10 +17,11 @@ namespace :api_docs do
16
17
  readme_api_endpoint = "https://dash.readme.com/api/v1/api-specification"
17
18
 
18
19
  # Read the OpenAPI schema file
19
- unless File.exist?(ApiRegulator.configuration.docs_path)
20
- raise "OpenAPI schema file not found at #{ApiRegulator.configuration.docs_path}"
20
+ schema_path = "#{ApiRegulator.configuration.docs_path}/openapi.json"
21
+ unless File.exist?(schema_path)
22
+ raise "OpenAPI schema file not found at #{schema_path}"
21
23
  end
22
- openapi_content = File.read(ApiRegulator.configuration.docs_path)
24
+ openapi_content = File.read(schema_path)
23
25
 
24
26
  # Upload to ReadMe
25
27
  require 'net/http'
@@ -63,5 +65,134 @@ namespace :api_docs do
63
65
  task publish: :environment do
64
66
  Rake::Task["api_docs:generate"].invoke
65
67
  Rake::Task["api_docs:upload"].invoke
68
+ Rake::Task["api_docs:upload_pages"].invoke
69
+ end
70
+
71
+ desc "Upload custom pages to ReadMe"
72
+ task :upload_pages => :environment do
73
+ # Configuration
74
+ readme_api_key = ENV['RDME_API_KEY'] || raise("RDME_API_KEY is not set")
75
+ base_readme_api_endpoint = "https://dash.readme.com/api/v1/docs"
76
+
77
+ # Discover all documentation files
78
+ pages_directory = "#{ApiRegulator.configuration.docs_path}/**/*.md"
79
+ page_files = Dir.glob(pages_directory)
80
+
81
+ # Iterate through each file
82
+ page_files.each do |file_path|
83
+ # Extract metadata and body
84
+ metadata, body = parse_markdown_file(file_path)
85
+ raise "No metadata found in #{file_path}" unless metadata
86
+
87
+ # Use metadata to build the API request
88
+ slug = metadata["slug"] || File.basename(file_path, ".md").gsub("_", "-")
89
+ body = {
90
+ type: "basic",
91
+ categorySlug: "documentation",
92
+ hidden: false
93
+ }.merge(metadata)
94
+ body["slug"] ||= slug
95
+
96
+ raise("Title missing in #{file_path}") unless body["title"].present?
97
+
98
+ # Build the API request
99
+ if check_if_page_exists(slug)
100
+ uri = URI.parse("#{base_readme_api_endpoint}/#{slug}")
101
+ request = Net::HTTP::Put.new(uri)
102
+ else
103
+ uri = URI.parse("#{base_readme_api_endpoint}")
104
+ request = Net::HTTP::Post.new(uri)
105
+ end
106
+ request["Authorization"] = "Basic #{Base64.strict_encode64(readme_api_key)}"
107
+ request["Content-Type"] = "application/json"
108
+ request.body = body.compact.to_json
109
+
110
+ # Send the request
111
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
112
+ http.request(request)
113
+ end
114
+
115
+ # Handle the response
116
+ case response.code.to_i
117
+ when 200
118
+ puts "Page '#{body["title"]}' successfully updated!"
119
+ when 201
120
+ puts "Page '#{body["title"]}' successfully created!"
121
+ else
122
+ puts "Failed to upload page '#{body["title"]}'!"
123
+ puts "Response Code: #{response.code}"
124
+ puts "Response Body: #{response.body}"
125
+ end
126
+ end
127
+ end
128
+
129
+ desc "View all categories on Readme.com"
130
+ task :fetch_categories => :environment do
131
+ # Configuration
132
+ readme_api_key = ENV['RDME_API_KEY'] || raise("RDME_API_KEY is not set")
133
+ readme_categories_api_endpoint = "https://dash.readme.com/api/v1/categories"
134
+
135
+ # Build the API request
136
+ uri = URI.parse(readme_categories_api_endpoint)
137
+ request = Net::HTTP::Get.new(uri)
138
+ request["Authorization"] = "Basic #{Base64.strict_encode64(readme_api_key)}"
139
+ request["Content-Type"] = "application/json"
140
+
141
+ # Send the request
142
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
143
+ http.request(request)
144
+ end
145
+
146
+ # Handle the response
147
+ case response.code.to_i
148
+ when 200
149
+ puts "Categories"
150
+ pp JSON.parse(response.body)
151
+ else
152
+ puts "Failed to fetch categories"
153
+ puts "Response Code: #{response.code}"
154
+ puts "Response Body: #{response.body}"
155
+ end
156
+ end
157
+
158
+ def parse_markdown_file(file_path)
159
+ content = File.read(file_path)
160
+ metadata = nil
161
+ body = ""
162
+
163
+ # Split metadata and body
164
+ if content =~ /\A---\s*\n(.*?)\n---\s*\n(.*)/m
165
+ metadata = YAML.safe_load($1)
166
+ body = $2
167
+ else
168
+ raise "YAML front matter missing in #{file_path}"
169
+ end
170
+
171
+ [metadata, body]
172
+ end
173
+
174
+ def check_if_page_exists(slug)
175
+ readme_api_key = ENV['RDME_API_KEY'] || raise("RDME_API_KEY is not set")
176
+ uri = URI.parse("https://dash.readme.com/api/v1/docs/#{slug}")
177
+ request = Net::HTTP::Get.new(uri)
178
+ request["Authorization"] = "Basic #{Base64.strict_encode64(readme_api_key)}"
179
+ request["Content-Type"] = "application/json"
180
+
181
+ # Send the request
182
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
183
+ http.request(request)
184
+ end
185
+
186
+ # Handle the response
187
+ case response.code.to_i
188
+ when 200
189
+ true
190
+ when 404
191
+ false
192
+ else
193
+ puts "Failed to serach for page"
194
+ puts "Response Code: #{response.code}"
195
+ puts "Response Body: #{response.body}"
196
+ end
66
197
  end
67
198
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-regulator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Massanek
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-13 00:00:00.000000000 Z
11
+ date: 2024-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -152,10 +152,12 @@ files:
152
152
  - lib/api_regulator/formats.rb
153
153
  - lib/api_regulator/open_api_generator.rb
154
154
  - lib/api_regulator/param.rb
155
+ - lib/api_regulator/security.rb
155
156
  - lib/api_regulator/shared_schema.rb
156
157
  - lib/api_regulator/validation_error.rb
157
158
  - lib/api_regulator/validator.rb
158
159
  - lib/api_regulator/version.rb
160
+ - lib/api_regulator/webhook.rb
159
161
  - lib/tasks/api_regulator_tasks.rake
160
162
  homepage: https://github.com/Stellarcred/stellar-gears
161
163
  licenses: