Module: GrapeOAS::DocumentationExtension

Defined in:
lib/grape_oas/documentation_extension.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.generate_documentation(endpoint, api, key, default_format, cache_control, etag_value, options, namespace_filter) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/grape_oas/documentation_extension.rb', line 50

def self.generate_documentation(endpoint, api, key, default_format, cache_control, etag_value, options, namespace_filter)
  schema_type = if key == :oas2
                  :oas2
                elsif key == :oas3
                  :oas3
                else
                  parse_schema_type(endpoint.params[:oas]) || default_format
                end

  endpoint.header("Cache-Control", cache_control) if cache_control
  endpoint.header("ETag", etag_value) if etag_value

  # Resolve runtime options (like grape-swagger's OptionalObject)
  runtime_options = options.dup
  runtime_options[:host] = resolve_option(
    runtime_options[:host], endpoint.request, :host_with_port,
  )
  runtime_options[:base_path] = resolve_option(
    runtime_options[:base_path], endpoint.request, :script_name,
  )
  runtime_options[:namespace] = namespace_filter if namespace_filter

  GrapeOAS.generate(app: api, schema_type: schema_type, **runtime_options)
end

.parse_schema_type(value) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/grape_oas/documentation_extension.rb', line 99

def parse_schema_type(value)
  case value&.to_s
  when "2", "oas2", "swagger"
    :oas2
  when "3.1", "31", "oas31", "oas3_1", "openapi31"
    :oas31
  when "3", "oas3", "openapi", "oas30", "oas3_0", "openapi30"
    :oas3
  end
end

.resolve_option(value, request, default_method) ⇒ Object

Resolve option value at request time (like grape-swagger’s OptionalObject) Supports: static values, Proc/lambda (with optional request arg), or fallback to request method



113
114
115
116
117
118
119
120
121
# File 'lib/grape_oas/documentation_extension.rb', line 113

def resolve_option(value, request, default_method)
  if value.is_a?(Proc)
    value.arity.zero? ? value.call : value.call(request)
  elsif value
    value
  elsif request
    request.send(default_method)
  end
end

Instance Method Details

#add_documentation_routes(path, key, default_format, cache_control, etag_value, options, api) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/grape_oas/documentation_extension.rb', line 32

def add_documentation_routes(path, key, default_format, cache_control, etag_value, options, api)
  # Main route without namespace filter
  add_route(path) do
    GrapeOAS::DocumentationExtension.generate_documentation(
      self, api, key, default_format, cache_control, etag_value, options, nil,
    )
  end

  # Route with namespace filter: /swagger_doc/:namespace
  # Supports nested namespaces via *namespace (catches slashes)
  add_route("#{path}/*namespace") do
    namespace_filter = params[:namespace]&.sub(/\.json$/, "")
    GrapeOAS::DocumentationExtension.generate_documentation(
      self, api, key, default_format, cache_control, etag_value, options, namespace_filter,
    )
  end
end

#add_oas_documentation(**options) ⇒ Object

Primary entry for grape-oas documentation



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/grape_oas/documentation_extension.rb', line 6

def add_oas_documentation(**options)
  return if options.delete(:hide_documentation_path)

  # Prefer grape-oas namespaced options to avoid clashing with grape-swagger
  default_mount_path = options.delete(:oas_mount_path) ||
                       options.delete(:mount_path) ||
                       "/swagger_doc"
  default_format = options.delete(:oas_doc_version) ||
                   options.delete(:doc_version) ||
                   :oas3
  cache_control = options.delete(:cache_control)
  etag_value = options.delete(:etag)

  mount_paths = {
    default: default_mount_path,
    oas2: options.delete(:oas_mount_path_v2) || options.delete(:mount_path_v2),
    oas3: options.delete(:oas_mount_path_v3) || options.delete(:mount_path_v3)
  }.compact

  api = self

  mount_paths.each do |key, path|
    add_documentation_routes(path, key, default_format, cache_control, etag_value, options, api)
  end
end

#add_swagger_documentation(**options) ⇒ Object

Compatibility shim for apps calling grape-swagger’s add_swagger_documentation.

If grape-swagger is loaded we defer to its implementation to keep legacy behaviour untouched. Only when grape-swagger is absent do we fall back to grape-oas.



80
81
82
83
84
85
86
87
# File 'lib/grape_oas/documentation_extension.rb', line 80

def add_swagger_documentation(**options)
  return super if defined?(::GrapeSwagger)

  options = options.dup
  options[:oas_doc_version] ||= :oas2
  options[:oas_mount_path] ||= options[:mount_path] || "/swagger_doc.json"
  add_oas_documentation(**options)
end