shaf 2.1.0 → 3.0.1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/shaf/app.rb +27 -9
  4. data/lib/shaf/command/base.rb +4 -0
  5. data/lib/shaf/command/new.rb +5 -1
  6. data/lib/shaf/command/server.rb +5 -1
  7. data/lib/shaf/command/templates/config/settings.yml.erb +9 -8
  8. data/lib/shaf/extensions/resource_uris.rb +37 -155
  9. data/lib/shaf/extensions/symbolic_routes.rb +5 -18
  10. data/lib/shaf/formable/builder.rb +58 -19
  11. data/lib/shaf/formable/form.rb +13 -10
  12. data/lib/shaf/formable.rb +10 -23
  13. data/lib/shaf/generator/base.rb +82 -0
  14. data/lib/shaf/generator/controller.rb +19 -35
  15. data/lib/shaf/generator/forms.rb +10 -14
  16. data/lib/shaf/generator/migration/add_column.rb +0 -4
  17. data/lib/shaf/generator/migration/add_index.rb +0 -4
  18. data/lib/shaf/generator/migration/base.rb +8 -0
  19. data/lib/shaf/generator/migration/create_table.rb +0 -4
  20. data/lib/shaf/generator/migration/drop_column.rb +0 -4
  21. data/lib/shaf/generator/migration/rename_column.rb +0 -4
  22. data/lib/shaf/generator/model.rb +29 -14
  23. data/lib/shaf/generator/policy.rb +8 -14
  24. data/lib/shaf/generator/profile.rb +9 -14
  25. data/lib/shaf/generator/scaffold.rb +6 -9
  26. data/lib/shaf/generator/serializer.rb +31 -30
  27. data/lib/shaf/generator/templates/api/controller.rb.erb +13 -13
  28. data/lib/shaf/generator/templates/api/forms.rb.erb +2 -2
  29. data/lib/shaf/generator/templates/api/model.rb.erb +1 -1
  30. data/lib/shaf/generator/templates/api/profile.rb.erb +1 -1
  31. data/lib/shaf/generator/templates/api/serializer.rb.erb +1 -1
  32. data/lib/shaf/generator/templates/spec/integration_spec.rb.erb +14 -14
  33. data/lib/shaf/helpers/paginate.rb +1 -1
  34. data/lib/shaf/link_relations.rb +77 -0
  35. data/lib/shaf/profile.rb +8 -8
  36. data/lib/shaf/registrable_factory.rb +62 -32
  37. data/lib/shaf/responder/problem_json.rb +1 -1
  38. data/lib/shaf/router.rb +65 -12
  39. data/lib/shaf/spec/integration_spec.rb +1 -1
  40. data/lib/shaf/tasks.rb +0 -1
  41. data/lib/shaf/upgrade/package.rb +5 -7
  42. data/lib/shaf/utils.rb +2 -2
  43. data/lib/shaf/version.rb +1 -1
  44. data/lib/shaf/yard/link_object.rb +2 -3
  45. data/templates/Rakefile +0 -6
  46. data/templates/api/controllers/base_controller.rb +0 -2
  47. data/templates/api/serializers/root_serializer.rb +0 -11
  48. data/templates/config/initializers/middleware.rb +6 -0
  49. data/templates/spec/spec_helper.rb +4 -1
  50. data/upgrades/3.0.0.tar.gz +0 -0
  51. data/yard_templates/api_doc/profile_attribute/html/attribute.erb +2 -1
  52. data/yard_templates/api_doc/resource_attribute/html/attribute.erb +2 -1
  53. data/yard_templates/api_doc/sidebar/html/profile_list.erb +2 -1
  54. data/yard_templates/api_doc/sidebar/html/serializer_list.erb +2 -1
  55. data.tar.gz.sig +0 -0
  56. metadata +34 -36
  57. metadata.gz.sig +0 -0
  58. data/lib/shaf/api_doc/comment.rb +0 -27
  59. data/lib/shaf/api_doc/document.rb +0 -137
  60. data/lib/shaf/api_doc/link_relations.rb +0 -77
  61. data/lib/shaf/middleware.rb +0 -1
  62. data/lib/shaf/tasks/api_doc_task.rb +0 -146
data/lib/shaf/router.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shaf/middleware'
4
3
  require 'set'
4
+ require 'sinatra'
5
+ require 'shaf/errors'
5
6
 
6
7
  module Shaf
7
8
  class Router
@@ -21,16 +22,56 @@ module Shaf
21
22
  end
22
23
  end
23
24
 
25
+ class NullController
26
+ def call(env)
27
+ request = request(env)
28
+ responder = Responder.for(request, error)
29
+ responder.call(self, error)
30
+
31
+ response.finish
32
+ end
33
+
34
+ # Called from responder
35
+ def content_type(mime)
36
+ response["Content-Type"] = mime
37
+ end
38
+
39
+ # Called from responder
40
+ def body(body)
41
+ response.body = body
42
+ end
43
+
44
+ private
45
+
46
+ def status
47
+ 500
48
+ end
49
+
50
+ def request(env)
51
+ Sinatra::Request.new(env)
52
+ end
53
+
54
+ def response
55
+ @response ||= Sinatra::Response.new(nil, status)
56
+ end
57
+
58
+ def error
59
+ @error ||= Errors::ServerError.new(
60
+ 'Internal error: No controller has been mounted on Router',
61
+ code: 'NO_MOUNTED_CONTROLLERS',
62
+ title: 'Shaf::Router must have at least one mounted controller',
63
+ )
64
+ end
65
+ end
66
+
24
67
  class << self
25
68
  def mount(controller, default: false)
26
69
  @default_controller = controller if default
27
- @controllers ||= []
28
- @controllers << controller
70
+ controllers << controller
29
71
  end
30
72
 
31
73
  def routes
32
- init_routes unless defined? @routes
33
- @routes
74
+ @routes ||= init_routes
34
75
  end
35
76
 
36
77
  # This controller will be used when no other can handle the request
@@ -41,32 +82,44 @@ module Shaf
41
82
 
42
83
  private
43
84
 
44
- attr_reader :controllers
85
+ def controllers
86
+ @controllers ||= []
87
+ end
45
88
 
46
89
  def init_routes
47
- @routes = Hash.new do |hash, key|
90
+ routes = Hash.new do |hash, key|
48
91
  hash[key] = Hash.new { |h, k| h[k] = Set.new }
49
92
  end
50
- controllers.each { |controller| init_routes_for(controller) }
93
+ controllers.each { |controller| init(controller, routes) }
94
+ routes
51
95
  end
52
96
 
53
- def init_routes_for(controller)
97
+ def init(controller, routes)
54
98
  controller.routes.each do |method, controller_routes|
55
99
  routes[method][controller] += controller_routes.map(&:first)
56
100
  end
57
101
  end
58
102
  end
59
103
 
60
- def initialize(app)
104
+ def initialize(app = NullController.new)
61
105
  @app = app
62
106
  end
63
107
 
64
108
  def call(env)
109
+ # When the api is mounted in Rails then the mount point will be not be
110
+ # present in PATH_INFO but it will instead be available in SCRIPT_NAME
111
+ # Shaf need to know about the full path in order to make all path helpers
112
+ # work, so we need to add the mountpoint back to PATH_INFO.
113
+ unless String(env['SCRIPT_NAME']).empty?
114
+ env['PATH_INFO'] = '' if env['PATH_INFO'] == '/'
115
+ env['PATH_INFO'] = "#{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
116
+ end
117
+
65
118
  http_method, path = http_details(env)
66
119
 
67
120
  result = nil
68
121
 
69
- controllers_for(http_method, path) do |controller|
122
+ each_controller_for(http_method, path) do |controller|
70
123
  result = controller.call(env)
71
124
  break unless cascade? result
72
125
  end
@@ -80,7 +133,7 @@ module Shaf
80
133
  [env['REQUEST_METHOD'], env['PATH_INFO']]
81
134
  end
82
135
 
83
- def controllers_for(http_method, path)
136
+ def each_controller_for(http_method, path)
84
137
  find_cached(http_method, path).each { |ctrlr| yield ctrlr }
85
138
 
86
139
  if controller = find(http_method, path)
@@ -30,7 +30,7 @@ module Shaf
30
30
  end
31
31
 
32
32
  def app
33
- App.app
33
+ App.instance
34
34
  end
35
35
 
36
36
  def authenticate(user)
data/lib/shaf/tasks.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'shaf/tasks/test_task'
2
2
  require 'shaf/tasks/db_task'
3
- require 'shaf/tasks/api_doc_task'
4
3
  require 'shaf/tasks/routes_task'
5
4
 
6
5
  module Shaf
@@ -236,18 +236,16 @@ module Shaf
236
236
  replacement = params[:replace]
237
237
 
238
238
  changed = false
239
- tmp = Tempfile.open do |new_file|
239
+ new_content = ""
240
+ FT::ChangeFileCommand.execute(file) do
240
241
  File.readlines(file).each do |line|
241
242
  changed = line.gsub!(pattern, replacement) || changed
242
- new_file << line
243
+ new_content << line
243
244
  end
244
- new_file
245
+ new_content
245
246
  end
246
247
 
247
- return true unless changed
248
-
249
- puts "modifying file: #{file}"
250
- FT::MoveFileCommand.new(from: tmp.path, to: file).execute
248
+ puts "modifying file: #{file}" if changed
251
249
  true
252
250
  end
253
251
 
data/lib/shaf/utils.rb CHANGED
@@ -107,9 +107,9 @@ module Shaf
107
107
  end
108
108
  end
109
109
 
110
- def iana_link_relations_csv
110
+ def iana_link_relations
111
111
  zip_file = File.join(gem_root, 'iana_link_relations.csv.gz')
112
- Zlib::GzipReader.open(zip_file) { |content| CSV.new(content.read) }
112
+ Zlib::GzipReader.open(zip_file) { |content| content.read }
113
113
  end
114
114
 
115
115
  private
data/lib/shaf/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shaf
4
- VERSION = '2.1.0'
4
+ VERSION = '3.0.1'
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shaf/api_doc/link_relations'
3
+ require 'shaf/link_relations'
4
4
 
5
5
  module Shaf
6
6
  module Yard
@@ -52,8 +52,7 @@ module Shaf
52
52
  end
53
53
 
54
54
  def iana_doc
55
- ApiDoc::LinkRelations.load_iana
56
- ApiDoc::LinkRelations[name.to_sym]&.description
55
+ LinkRelations.get(name)&.description
57
56
  end
58
57
  end
59
58
  end
data/templates/Rakefile CHANGED
@@ -5,12 +5,6 @@ $LOAD_PATH.unshift __dir__ unless $LOAD_PATH.include? __dir__
5
5
  require 'shaf/rake'
6
6
  require 'shaf/settings'
7
7
 
8
- Shaf::ApiDocTask.new do |api_doc|
9
- api_doc.source_dir = File.join(%w(api serializers))
10
- api_doc.html_output_dir = File.join(Shaf::Settings.public_folder, "doc")
11
- api_doc.yaml_output_dir = Shaf::Settings.documents_dir || "doc/api"
12
- end
13
-
14
8
  namespace :test do
15
9
  Shaf::TestTask.new(:integration) do |t|
16
10
  t.pattern = "spec/integration/**/*_spec.rb"
@@ -13,8 +13,6 @@ class BaseController < Sinatra::Base
13
13
  set :show_exceptions, :after_handler
14
14
  end
15
15
 
16
- use Rack::Deflater
17
-
18
16
  Shaf::Router.mount(self, default: true)
19
17
 
20
18
  register(*Shaf.extensions)
@@ -1,16 +1,5 @@
1
1
  require 'serializers/base_serializer'
2
2
 
3
3
  class RootSerializer < BaseSerializer
4
-
5
- # Auto generated doc:
6
- # Link to the root resource. All clients should fetch this resource
7
- # when starting to interact with this API.
8
- # Method: GET
9
- # Example:
10
- # ```
11
- # curl -H "Accept: application/json" \
12
- # -H "Authorization: abcdef" \
13
- # /
14
- #```
15
4
  link :self, root_uri
16
5
  end
@@ -0,0 +1,6 @@
1
+ require 'shaf/middleware/request_id'
2
+ require 'shaf/router'
3
+
4
+ Shaf::App.use Rack::Deflater
5
+ Shaf::App.use Shaf::Middleware::RequestId
6
+ Shaf::App.use Shaf::Router
@@ -4,4 +4,7 @@ require 'minitest/autorun'
4
4
  require 'minitest/hooks'
5
5
  require 'shaf/spec'
6
6
 
7
- Shaf::Spec::Authenticator.restricted { |id:| User[id] }
7
+ realm = Shaf::Settings.default_authentication_realm
8
+ Shaf::Spec::Authenticator.restricted realm: realm do |id:|
9
+ User[id]
10
+ end
Binary file
@@ -1,6 +1,7 @@
1
1
  <h4 class=description-list>
2
2
  <strong> <%= object.name %></strong>
3
- <% value_types.each do |type:, class_name:| %>
3
+ <% value_types.each do |value_type| %>
4
+ <% type, class_name = value_type.values_at(:type, :class_name) %>
4
5
  <span class="property-source <%= class_name %>"><%= type %></span>
5
6
  <% end %>
6
7
  </h4>
@@ -1,6 +1,7 @@
1
1
  <h4 class=description-list>
2
2
  <strong> <%= object.name %></strong>
3
- <% value_types.each do |type:, class_name:| %>
3
+ <% value_types.each do |value_type| %>
4
+ <% type, class_name = value_type.values_at(:type, :class_name) %>
4
5
  <span class="property-source <%= class_name %>"><%= type %></span>
5
6
  <% end %>
6
7
  </h4>
@@ -1,6 +1,7 @@
1
1
  <div id="profile-list" class="list sidebar-content <%= 'active' if profile? %>">
2
2
  <ul>
3
- <% @profiles.each do |name:, path:| %>
3
+ <% @profiles.each do |profile| %>
4
+ <% name, path = profile.values_at(:name, :path) %>
4
5
  <li class="sidebar-link <%= 'active' if profile_active?(name) %>">
5
6
  <a href=<%= path %> class="<%= 'active' if profile_active?(name) %>"><%= name%></a>
6
7
  </li>
@@ -1,6 +1,7 @@
1
1
  <div id="serializer-list" class="list sidebar-content <%= 'active' if resource? || index? %>">
2
2
  <ul>
3
- <% @resources.each do |name:, path:| %>
3
+ <% @resources.each do |resource| %>
4
+ <% name, path = resource.values_at(:name, :path) %>
4
5
  <li class="sidebar-link <%= 'active' if resource_active?(name) %>">
5
6
  <a href=<%= path %> class="<%= 'active' if resource_active?(name) %>"><%= name%></a>
6
7
  </li>
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,18 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shaf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
13
  MIIDVjCCAj6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDDB9zYW1t
14
- eS5oZW5uaW5nc3Nvbi9EQz1oZXkvREM9Y29tMB4XDTIxMDIwMjEzNTY1OFoXDTIy
15
- MDIwMjEzNTY1OFowKjEoMCYGA1UEAwwfc2FtbXkuaGVubmluZ3Nzb24vREM9aGV5
14
+ eS5oZW5uaW5nc3Nvbi9EQz1oZXkvREM9Y29tMB4XDTIzMDkwMjIxMDQ1MVoXDTI1
15
+ MDkwMTIxMDQ1MVowKjEoMCYGA1UEAwwfc2FtbXkuaGVubmluZ3Nzb24vREM9aGV5
16
16
  L0RDPWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+SDC1mfyhu
17
17
  cJ6Va21rIHUGscEtQrdvyBqxFG1s2TgPMAv4RbqwdJVPa7kjtbCzslADlUE1oru2
18
18
  C+rcJsMtVGX02ukMIPHT1OjTyy0/EMqLqSy3WeRI8APyDSxCVbe+h5BMf3zZnYfd
@@ -22,14 +22,14 @@ cert_chain:
22
22
  nIxTSJpPr2cCAwEAAaOBhjCBgzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV
23
23
  HQ4EFgQUukjj1Cd2ea6IOHDLZe0ymzs2jWkwJAYDVR0RBB0wG4EZc2FtbXkuaGVu
24
24
  bmluZ3Nzb25AaGV5LmNvbTAkBgNVHRIEHTAbgRlzYW1teS5oZW5uaW5nc3NvbkBo
25
- ZXkuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBt310FZ56E/fp/y5Wym1xb4C0owfnI
26
- LzUqOjXWZTO7RezlBJV/qIwqt6bEjYDQR56zULJFSp4YdoDsratmQ+/kwtbHF7xf
27
- WYkSE36mhLP2ggQFH9fXtX6XdyIlwFqwEfNW73ZrkBXGjMxLVKIS9uHdN7PoNhbS
28
- 0YjOZZD/rq1Jf+klwl/G7bBDPjn58DWlUmwzoj49goGS/UBG37RssQxRwPelKHZh
29
- 5ZlcHq9h5CxVt380OKaU6wMg95RJBd/kUJqmPxxlxMH8QDQinTwZmmFA9wW7PJdy
30
- wAx8px9LkSjTs0GVLH7VtVRWAELllsswCJktz63Adelx9fmIMgrTYgZM
25
+ ZXkuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAsxqfXdj/fWsDuJmENnfpYLkPJ96MS
26
+ 8GcxCGRaq2k5nZlGU38tPzTm9HdOjCOouO4PthohqNQ9X7jOkSbKA/zrGGTHyao9
27
+ 0URFQQ/ln3liGyjD4FsXSVZVBqbw9U0AGXh9MwatyWBj9Q679SttxCIGYJtNwtVo
28
+ jCXrgrCX+Slrrlfi7ve5Dz/V9bhl2jZrv4d2rIuMBJCHPr8sa/nobyskfYgs0v2D
29
+ Dw5VdKSj3KIY2gdwi1boraHAMinBgq6VXJczYUhdWtQln+0GFS1XHf1dBlCSZCTN
30
+ trIX62sesXxQtqAqHQHNIbWC2vP1K04nAzyw4ohA0yTAo/Hscqusp+If
31
31
  -----END CERTIFICATE-----
32
- date: 2021-04-07 00:00:00.000000000 Z
32
+ date: 2023-09-02 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: file_transactions
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '5'
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: '5.14'
57
+ version: '5.19'
58
58
  type: :development
59
59
  prerelease: false
60
60
  version_requirements: !ruby/object:Gem::Requirement
@@ -64,7 +64,7 @@ dependencies:
64
64
  version: '5'
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '5.14'
67
+ version: '5.19'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: rack-test
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -149,20 +149,6 @@ dependencies:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
151
  version: '0.9'
152
- - !ruby/object:Gem::Dependency
153
- name: redcarpet
154
- requirement: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '3.5'
159
- type: :development
160
- prerelease: false
161
- version_requirements: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '3.5'
166
152
  - !ruby/object:Gem::Dependency
167
153
  name: faraday
168
154
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +205,20 @@ dependencies:
219
205
  - - "~>"
220
206
  - !ruby/object:Gem::Version
221
207
  version: '1.6'
208
+ - !ruby/object:Gem::Dependency
209
+ name: byebug
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ type: :development
216
+ prerelease: false
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
222
  description: A framework for building hypermedia driven APIs with sinatra and sequel.
223
223
  email: sammy.henningsson@gmail.com
224
224
  executables:
@@ -232,9 +232,6 @@ files:
232
232
  - lib/shaf/alps/attribute_serializer.rb
233
233
  - lib/shaf/alps/json_serializer.rb
234
234
  - lib/shaf/alps/relation_serializer.rb
235
- - lib/shaf/api_doc/comment.rb
236
- - lib/shaf/api_doc/document.rb
237
- - lib/shaf/api_doc/link_relations.rb
238
235
  - lib/shaf/app.rb
239
236
  - lib/shaf/authenticator.rb
240
237
  - lib/shaf/authenticator/base.rb
@@ -307,8 +304,8 @@ files:
307
304
  - lib/shaf/helpers/payload.rb
308
305
  - lib/shaf/helpers/vary.rb
309
306
  - lib/shaf/immutable_attr.rb
307
+ - lib/shaf/link_relations.rb
310
308
  - lib/shaf/logger.rb
311
- - lib/shaf/middleware.rb
312
309
  - lib/shaf/middleware/request_id.rb
313
310
  - lib/shaf/parser.rb
314
311
  - lib/shaf/parser/base.rb
@@ -352,7 +349,6 @@ files:
352
349
  - lib/shaf/spec/system_spec.rb
353
350
  - lib/shaf/supported_http_methods.rb
354
351
  - lib/shaf/tasks.rb
355
- - lib/shaf/tasks/api_doc_task.rb
356
352
  - lib/shaf/tasks/db_task.rb
357
353
  - lib/shaf/tasks/routes_task.rb
358
354
  - lib/shaf/tasks/test_task.rb
@@ -397,6 +393,7 @@ files:
397
393
  - templates/config/initializers/db_migrations.rb
398
394
  - templates/config/initializers/hal_presenter.rb
399
395
  - templates/config/initializers/logging.rb
396
+ - templates/config/initializers/middleware.rb
400
397
  - templates/config/initializers/sequel.rb
401
398
  - templates/config/paths.rb
402
399
  - templates/frontend/assets/css/main.css
@@ -422,6 +419,7 @@ files:
422
419
  - upgrades/1.6.0.tar.gz
423
420
  - upgrades/1.6.1.tar.gz
424
421
  - upgrades/2.0.0.tar.gz
422
+ - upgrades/3.0.0.tar.gz
425
423
  - yard_templates/api_doc/doc_index/html/body.erb
426
424
  - yard_templates/api_doc/doc_index/setup.rb
427
425
  - yard_templates/api_doc/html/css/api-doc.css
@@ -455,13 +453,13 @@ files:
455
453
  - yard_templates/api_doc/sidebar/html/serializer_list.erb
456
454
  - yard_templates/api_doc/sidebar/html/sidebar.erb
457
455
  - yard_templates/api_doc/sidebar/setup.rb
458
- homepage:
456
+ homepage:
459
457
  licenses:
460
458
  - MIT
461
459
  metadata:
462
460
  changelog_uri: https://github.com/sammyhenningsson/shaf/blob/master/CHANGELOG.md
463
461
  homepage_uri: https://github.com/sammyhenningsson/shaf
464
- post_install_message:
462
+ post_install_message:
465
463
  rdoc_options: []
466
464
  require_paths:
467
465
  - lib
@@ -476,8 +474,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
476
474
  - !ruby/object:Gem::Version
477
475
  version: '0'
478
476
  requirements: []
479
- rubygems_version: 3.0.3
480
- signing_key:
477
+ rubygems_version: 3.4.18
478
+ signing_key:
481
479
  specification_version: 4
482
480
  summary: Sinatra Hypermedia Api Framework
483
481
  test_files: []
metadata.gz.sig CHANGED
Binary file
@@ -1,27 +0,0 @@
1
- module Shaf
2
- module ApiDoc
3
- class Comment
4
- def initialize
5
- @indent = 0
6
- @comment = ""
7
- end
8
-
9
- def to_s
10
- @comment
11
- end
12
-
13
- def empty?
14
- @comment.empty?
15
- end
16
-
17
- def <<(line)
18
- @indent = line[/\A\s*/].size if empty?
19
- @comment << "\n#{extract(line)}"
20
- end
21
-
22
- def extract(line)
23
- line.sub(%r(\A\s{#{@indent}}), "")
24
- end
25
- end
26
- end
27
- end
@@ -1,137 +0,0 @@
1
- require 'fileutils'
2
- require 'yaml'
3
- require 'redcarpet'
4
- require 'redcarpet/render_strip'
5
-
6
- module Shaf
7
- module ApiDoc
8
- class Document
9
- attr_writer :model
10
- attr_accessor :serializer_class, :policy, :attributes, :links, :curies, :embeds
11
-
12
- def initialize
13
- @model = nil
14
- @serializer_class = nil
15
- @policy = nil
16
- @attributes = {}
17
- @links = {}
18
- @curies = {}
19
- @embeds = {}
20
- @md = {}
21
- end
22
-
23
- def model
24
- @model || @serializer_class && @serializer_class.sub("Serializer", "")
25
- end
26
-
27
- def attribute(attr, comment)
28
- @attributes[attr] = comment unless comment.empty?
29
- end
30
-
31
- def link(rel, comment)
32
- @links[strip_curie(rel)] = comment unless comment.empty?
33
- end
34
-
35
- def curie(rel, comment)
36
- @curies[rel] = comment unless comment.empty?
37
- end
38
-
39
- def embedded(name, comment)
40
- @embeds[strip_curie(name)] = comment unless comment.empty?
41
- end
42
-
43
- def valid?
44
- return false unless model
45
- attributes.merge(links).merge(curies).any?
46
- end
47
-
48
- def generate_markdown!
49
- return @md unless @md.empty?
50
-
51
- generate_title!
52
- generate_policy!
53
- generate_section!(key: :attributes, heading: "Attributes")
54
- generate_section!(key: :curies, heading: "Curies", sub_title: "rel")
55
- generate_section!(key: :links, heading: "Links", sub_title: "rel")
56
- generate_section!(key: :embeds, heading: "Embedded resources", sub_title: "rel")
57
- @md[:doc]
58
- end
59
-
60
- def generate_yaml!
61
- generate_markdown!
62
- renderer = Redcarpet::Markdown.new(Redcarpet::Render::StripDown)
63
-
64
- hash = {}
65
- hash['policy'] = renderer.render(@md[:policy]).chomp if @md[:policy]
66
-
67
- [:attributes, :curies, :links, :embeds].each do |key|
68
- hash[key.to_s] = @md[key].map { |k, v| [k.to_s, renderer.render(v).chomp] }.to_h
69
- end
70
- hash.to_yaml
71
- end
72
-
73
- def markdown
74
- generate_markdown!
75
- @md[:doc]
76
- end
77
-
78
- def to_html
79
- options = {autolink: true, fenced_code_blocks: true}
80
- markdown_renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options)
81
- html = markdown_renderer.render markdown
82
- # For some reason redcarpet don't like to surround my markdown code blocks
83
- # with <pre> tags, so let's fix that here.
84
- html.gsub!("<code>", "<pre><code>")
85
- html.gsub!("</code>", "</code></pre>")
86
- html
87
- end
88
-
89
- def write_html(output)
90
- FileUtils.mkdir_p(output) unless Dir.exist? output
91
- File.open(File.join(output, "#{model.downcase}.html"), "w") do |file|
92
- file.write(to_html)
93
- end
94
- end
95
-
96
- def write_yaml(output)
97
- FileUtils.mkdir_p(output) unless Dir.exist? output
98
- File.open(File.join(output, "#{model.downcase}.yml"), "w") do |file|
99
- file.write(generate_yaml!)
100
- end
101
- end
102
-
103
-
104
- private
105
-
106
- def strip_curie(rel)
107
- rel.split(':', 2)[1] || rel
108
- end
109
-
110
- def generate_title!
111
- @md[:doc] = "# #{model.capitalize}\n"
112
- @md[:title] = model.capitalize
113
- end
114
-
115
- def generate_policy!
116
- return if policy.nil?
117
- @md[:doc] << "## Policy\n#{policy}\n"
118
- @md[:policy] = policy
119
- end
120
-
121
- def generate_section!(key:, heading:, sub_title: "")
122
- list = send(key)
123
- @md[:doc] << "## #{heading}\n"
124
- @md[key] = {}
125
- if list.empty?
126
- @md[:doc] << "This resource does not have any documented #{heading.downcase}\n"
127
- else
128
- sub_title += ": " unless sub_title.empty?
129
- list.each do |name, comment|
130
- @md[:doc] << "- *#{sub_title}#{name.tr('_', '-')}*\n #{comment.to_s.gsub("\n", "\n ")}\n\n"
131
- @md[key][name] = comment.to_s.chomp
132
- end
133
- end
134
- end
135
- end
136
- end
137
- end