oas_hanami 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 +7 -0
- data/.release-please-config.json +64 -0
- data/.release-please-manifest.json +3 -0
- data/.rspec +4 -0
- data/.rspec_status +11 -0
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +20 -0
- data/.ruby-version +1 -0
- data/.ruby.version +1 -0
- data/CHANGELOG.md +8 -0
- data/README.md +38 -0
- data/Rakefile +11 -0
- data/lib/oas_hanami/configuration.rb +63 -0
- data/lib/oas_hanami/hanami_route_formatter.rb +9 -0
- data/lib/oas_hanami/inspector.rb +11 -0
- data/lib/oas_hanami/oas_route_builder.rb +90 -0
- data/lib/oas_hanami/route_extractor.rb +46 -0
- data/lib/oas_hanami/version.rb +5 -0
- data/lib/oas_hanami/web/assets/rapidoc-min.js +3915 -0
- data/lib/oas_hanami/web/view.rb +35 -0
- data/lib/oas_hanami/web/views/index.html.erb +154 -0
- data/lib/oas_hanami.rb +47 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a54ec2dcc566a43373e6345ad0dc9d5f6ce21decbb6ac136fadf3327241bf59e
|
4
|
+
data.tar.gz: ecec0f8eb9cc753bb89d6f9e47c05e90960a1273c983a2cec114057530f4cd0d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e16468c06d74fba996631455a353d9ada8da46b61b17aa0892ad6d58ce7a8b32f635020fd11dde6090c05cc726cec2269c2e4d4f41cf130746fe16dcf67a4f48
|
7
|
+
data.tar.gz: f7846391ca5a5cb186083ee9cc62eb57556fd00c36287047aff424160aff588a5e963b5a2c62b5d8549b9494bdb0ab1b102d6ae257d689e03cbb32080b936996
|
@@ -0,0 +1,64 @@
|
|
1
|
+
{
|
2
|
+
"release-type": "ruby",
|
3
|
+
"changelog-sections": [
|
4
|
+
{
|
5
|
+
"type": "feat",
|
6
|
+
"section": "Features"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"type": "feature",
|
10
|
+
"section": "Features"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"type": "fix",
|
14
|
+
"section": "Bug Fixes"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"type": "perf",
|
18
|
+
"section": "Performance Improvements"
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"type": "revert",
|
22
|
+
"section": "Reverts"
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"type": "docs",
|
26
|
+
"section": "Documentation"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"type": "style",
|
30
|
+
"section": "Styles",
|
31
|
+
"hidden": true
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"type": "chore",
|
35
|
+
"section": "Miscellaneous Chores",
|
36
|
+
"hidden": true
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"type": "refactor",
|
40
|
+
"section": "Code Refactoring"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"type": "test",
|
44
|
+
"section": "Tests"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"type": "build",
|
48
|
+
"section": "Build System",
|
49
|
+
"hidden": true
|
50
|
+
},
|
51
|
+
{
|
52
|
+
"type": "ci",
|
53
|
+
"section": "Continuous Integration",
|
54
|
+
"hidden": true
|
55
|
+
}
|
56
|
+
],
|
57
|
+
"packages": {
|
58
|
+
".": {
|
59
|
+
"release-type": "ruby",
|
60
|
+
"package-name": "oas_hanami",
|
61
|
+
"version-file": "lib/oas_hanami/version.rb"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
data/.rspec
ADDED
data/.rspec_status
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
example_id | status | run_time |
|
2
|
+
-------------------------------------------------------------------- | ------ | --------------- |
|
3
|
+
./spec/bookshelf/spec/requests/books/create_spec.rb[1:1:1] | failed | 0.00294 seconds |
|
4
|
+
./spec/bookshelf/spec/requests/books/create_spec.rb[1:2:1] | failed | 0.00016 seconds |
|
5
|
+
./spec/bookshelf/spec/requests/books/index/pagination_spec.rb[1:1:1] | failed | 0.00012 seconds |
|
6
|
+
./spec/bookshelf/spec/requests/books/index/pagination_spec.rb[1:2:1] | failed | 0.00008 seconds |
|
7
|
+
./spec/bookshelf/spec/requests/books/index_spec.rb[1:1] | failed | 0.00008 seconds |
|
8
|
+
./spec/bookshelf/spec/requests/books/show_spec.rb[1:1:1] | failed | 0.00008 seconds |
|
9
|
+
./spec/bookshelf/spec/requests/books/show_spec.rb[1:2:1] | failed | 0.00007 seconds |
|
10
|
+
./spec/bookshelf/spec/requests/root_spec.rb[1:1] | failed | 0.00008 seconds |
|
11
|
+
./spec/oas_hanami_spec.rb[1:1] | passed | 0.00408 seconds |
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 3.1
|
5
|
+
NewCops: disable
|
6
|
+
SuggestExtensions: false
|
7
|
+
|
8
|
+
Style/StringLiterals:
|
9
|
+
EnforcedStyle: double_quotes
|
10
|
+
|
11
|
+
Style/StringLiteralsInInterpolation:
|
12
|
+
EnforcedStyle: double_quotes
|
13
|
+
|
14
|
+
Style/Documentation:
|
15
|
+
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-06-15 19:33:58 UTC using RuboCop version 1.76.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
11
|
+
# AllowedMethods: refine
|
12
|
+
Metrics/BlockLength:
|
13
|
+
Max: 31
|
14
|
+
|
15
|
+
# Offense count: 2
|
16
|
+
# This cop supports safe autocorrection (--autocorrect).
|
17
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
18
|
+
# URISchemes: http, https
|
19
|
+
Layout/LineLength:
|
20
|
+
Max: 235
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.4
|
data/.ruby.version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [0.1.0](https://github.com/a-chacon/oas_hanami/compare/oas_hanami-v0.0.1...oas_hanami/v0.1.0) (2025-06-15)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* initial release ([a622d09](https://github.com/a-chacon/oas_hanami/commit/a622d09d96243406eac3887e38c145fb0e962ac2))
|
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+

|
2
|
+

|
3
|
+

|
4
|
+

|
5
|
+

|
6
|
+

|
7
|
+
|
8
|
+
# 📃Open API Specification For Hanami
|
9
|
+
|
10
|
+
OasHanami is a tool for generating **automatic interactive documentation for your Hanami APIs**. It generates an **OAS 3.1** document and displays it using **[RapiDoc](https://rapidocweb.com)**.
|
11
|
+
|
12
|
+
Built for the modern [Hanami](https://hanamirb.org) framework, OasHanami leverages Hanami's lightweight and modular design, making it ideal for building scalable Ruby applications. It relies on the [OasCore](https://github.com/a-chacon/oas_core) gem for seamless OpenAPI integration.
|
13
|
+
|
14
|
+

|
15
|
+
|
16
|
+
## Documentation
|
17
|
+
|
18
|
+
For details on how to install, configure, and use OasHanami, please refer to the [OasCore MDBook](http://a-chacon.com/oas_core).
|
19
|
+
|
20
|
+
## Contributing
|
21
|
+
|
22
|
+
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star⭐! Thanks again!
|
23
|
+
|
24
|
+
If you plan a big feature, first open an issue to discuss it before any development.
|
25
|
+
|
26
|
+
1. Fork the Project
|
27
|
+
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
|
28
|
+
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
|
29
|
+
4. Push to the Branch (`git push origin feature/AmazingFeature`)
|
30
|
+
5. Open a Pull Request
|
31
|
+
|
32
|
+
## License
|
33
|
+
|
34
|
+
The gem is available as open source under the terms of the [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.en.html#license-text).
|
35
|
+
|
36
|
+
## Star History
|
37
|
+
|
38
|
+
[](https://www.star-history.com/#[USERNAME]/oas_hanami&Date)
|
data/Rakefile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OasHanami
|
4
|
+
class Configuration < OasCore::Configuration
|
5
|
+
attr_accessor :rapidoc_theme
|
6
|
+
attr_reader :include_mode
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super(info: generate_info_object)
|
10
|
+
|
11
|
+
@include_mode = :all
|
12
|
+
@rapidoc_theme = :hanami
|
13
|
+
end
|
14
|
+
|
15
|
+
def include_mode=(value)
|
16
|
+
valid_modes = %i[all with_tags explicit]
|
17
|
+
raise ArgumentError, "include_mode must be one of #{valid_modes}" unless valid_modes.include?(value)
|
18
|
+
|
19
|
+
@include_mode = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_info_object
|
23
|
+
OasCore::Spec::Info.new(
|
24
|
+
title: title,
|
25
|
+
summary: summary,
|
26
|
+
description: description
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def title
|
31
|
+
"OasHanami"
|
32
|
+
end
|
33
|
+
|
34
|
+
def summary
|
35
|
+
"OasHanami: Automatic Interactive API Documentation for Hanami"
|
36
|
+
end
|
37
|
+
|
38
|
+
def description
|
39
|
+
<<~DESC
|
40
|
+
# Welcome to OasHanami
|
41
|
+
|
42
|
+
OasHanami automatically generates interactive documentation for your Hanami APIs using the OpenAPI Specification 3.1 (OAS 3.1) and displays it with a sleek UI.
|
43
|
+
|
44
|
+
## Getting Started
|
45
|
+
|
46
|
+
You've successfully mounted the OasHanami engine. This default documentation is based on your routes and automatically gathered information.
|
47
|
+
|
48
|
+
For more details, visit the official documentation: [OasCore Documentation](https://a-chacon.com/oas_core).
|
49
|
+
|
50
|
+
## Features
|
51
|
+
|
52
|
+
- **Automatic OAS 3.1 Document Generation**: No manual specification required.
|
53
|
+
- **[RapiDoc](https://github.com/rapi-doc/RapiDoc) Integration**: Interactive API exploration.
|
54
|
+
- **Minimal Setup**: Basic documentation works out of the box.
|
55
|
+
- **Extensible**: Customize through configuration and YARD tags.
|
56
|
+
|
57
|
+
Explore your API documentation and enjoy the power of OasHanami!
|
58
|
+
|
59
|
+
Any questions visit the [OasHanami GitHub Repository](https://github.com/a-chacon/oas_hanami).
|
60
|
+
DESC
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OasHanami
|
4
|
+
class OasRouteBuilder
|
5
|
+
def self.build_from_hanami_route(hanami_route)
|
6
|
+
new(hanami_route).build
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(hanami_route)
|
10
|
+
@hanami_route = hanami_route
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
OasCore::OasRoute.new(
|
15
|
+
controller: controller,
|
16
|
+
method_name: method,
|
17
|
+
verb: verb,
|
18
|
+
path: path,
|
19
|
+
docstring: docstring,
|
20
|
+
source_string: source_string,
|
21
|
+
tags: tags
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def controller_class
|
28
|
+
if @hanami_route.to.is_a?(String)
|
29
|
+
namespace = Hanami.app.name.gsub("App", "Actions")
|
30
|
+
parts = @hanami_route.to.split(".")
|
31
|
+
full_class_name = "#{namespace}::#{parts.map(&:camelize).join("::")}"
|
32
|
+
|
33
|
+
full_class_name.split("::").reduce(Object) { |mod, name| mod.const_get(name) }
|
34
|
+
else
|
35
|
+
@hanami_route.to
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def controller
|
40
|
+
controller_class.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def method
|
44
|
+
"handle"
|
45
|
+
end
|
46
|
+
|
47
|
+
def verb
|
48
|
+
@hanami_route.http_method.downcase
|
49
|
+
end
|
50
|
+
|
51
|
+
def path
|
52
|
+
@hanami_route.path
|
53
|
+
end
|
54
|
+
|
55
|
+
def source_string
|
56
|
+
controller_class.instance_method(method).source
|
57
|
+
rescue NameError
|
58
|
+
"Source not available"
|
59
|
+
end
|
60
|
+
|
61
|
+
def docstring
|
62
|
+
comment_lines = controller_class.instance_method(method).comment.lines
|
63
|
+
processed_lines = comment_lines.map { |line| line.sub(/^# /, "") }
|
64
|
+
|
65
|
+
filtered_lines = processed_lines.reject do |line|
|
66
|
+
line.include?("rubocop") ||
|
67
|
+
line.include?("TODO")
|
68
|
+
end
|
69
|
+
|
70
|
+
::YARD::Docstring.parser.parse(filtered_lines.join).to_docstring
|
71
|
+
rescue NameError
|
72
|
+
"Docstring not available"
|
73
|
+
end
|
74
|
+
|
75
|
+
def tags
|
76
|
+
method_comment = controller_class.instance_method(method).comment
|
77
|
+
|
78
|
+
parse_tags(method_comment)
|
79
|
+
rescue NameError
|
80
|
+
[]
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_tags(comment)
|
84
|
+
return [] unless comment
|
85
|
+
|
86
|
+
lines = comment.lines.map { |line| line.sub(/^# /, "") }
|
87
|
+
::YARD::Docstring.parser.parse(lines.join).tags
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OasHanami
|
4
|
+
class RouteExtractor
|
5
|
+
class << self
|
6
|
+
def host_routes
|
7
|
+
@host_routes ||= extract_host_routes
|
8
|
+
end
|
9
|
+
|
10
|
+
def clear_cache
|
11
|
+
@host_routes = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def clean_route(route)
|
15
|
+
route.gsub("(.:format)", "").gsub(/:\w+/) { |match| "{#{match[1..]}}" }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def extract_host_routes
|
21
|
+
routes = Hanami.app.router.inspector.call
|
22
|
+
routes = transform_routes(routes)
|
23
|
+
filter_routes(routes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def transform_routes(routes)
|
27
|
+
routes.map do |r|
|
28
|
+
next unless r.to.is_a? String
|
29
|
+
|
30
|
+
OasRouteBuilder.build_from_hanami_route(r)
|
31
|
+
end.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
def filter_routes(routes)
|
35
|
+
case OasHanami.config.include_mode
|
36
|
+
when :with_tags
|
37
|
+
routes.select { |route| route.tags.any? }
|
38
|
+
when :explicit
|
39
|
+
routes.select { |route| route.tags.any? { |t| t.tag_name == "oas_include" } }
|
40
|
+
else
|
41
|
+
routes
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|