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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/shaf/app.rb +27 -9
- data/lib/shaf/command/base.rb +4 -0
- data/lib/shaf/command/new.rb +5 -1
- data/lib/shaf/command/server.rb +5 -1
- data/lib/shaf/command/templates/config/settings.yml.erb +9 -8
- data/lib/shaf/extensions/resource_uris.rb +37 -155
- data/lib/shaf/extensions/symbolic_routes.rb +5 -18
- data/lib/shaf/formable/builder.rb +58 -19
- data/lib/shaf/formable/form.rb +13 -10
- data/lib/shaf/formable.rb +10 -23
- data/lib/shaf/generator/base.rb +82 -0
- data/lib/shaf/generator/controller.rb +19 -35
- data/lib/shaf/generator/forms.rb +10 -14
- data/lib/shaf/generator/migration/add_column.rb +0 -4
- data/lib/shaf/generator/migration/add_index.rb +0 -4
- data/lib/shaf/generator/migration/base.rb +8 -0
- data/lib/shaf/generator/migration/create_table.rb +0 -4
- data/lib/shaf/generator/migration/drop_column.rb +0 -4
- data/lib/shaf/generator/migration/rename_column.rb +0 -4
- data/lib/shaf/generator/model.rb +29 -14
- data/lib/shaf/generator/policy.rb +8 -14
- data/lib/shaf/generator/profile.rb +9 -14
- data/lib/shaf/generator/scaffold.rb +6 -9
- data/lib/shaf/generator/serializer.rb +31 -30
- data/lib/shaf/generator/templates/api/controller.rb.erb +13 -13
- data/lib/shaf/generator/templates/api/forms.rb.erb +2 -2
- data/lib/shaf/generator/templates/api/model.rb.erb +1 -1
- data/lib/shaf/generator/templates/api/profile.rb.erb +1 -1
- data/lib/shaf/generator/templates/api/serializer.rb.erb +1 -1
- data/lib/shaf/generator/templates/spec/integration_spec.rb.erb +14 -14
- data/lib/shaf/helpers/paginate.rb +1 -1
- data/lib/shaf/link_relations.rb +77 -0
- data/lib/shaf/profile.rb +8 -8
- data/lib/shaf/registrable_factory.rb +62 -32
- data/lib/shaf/responder/problem_json.rb +1 -1
- data/lib/shaf/router.rb +65 -12
- data/lib/shaf/spec/integration_spec.rb +1 -1
- data/lib/shaf/tasks.rb +0 -1
- data/lib/shaf/upgrade/package.rb +5 -7
- data/lib/shaf/utils.rb +2 -2
- data/lib/shaf/version.rb +1 -1
- data/lib/shaf/yard/link_object.rb +2 -3
- data/templates/Rakefile +0 -6
- data/templates/api/controllers/base_controller.rb +0 -2
- data/templates/api/serializers/root_serializer.rb +0 -11
- data/templates/config/initializers/middleware.rb +6 -0
- data/templates/spec/spec_helper.rb +4 -1
- data/upgrades/3.0.0.tar.gz +0 -0
- data/yard_templates/api_doc/profile_attribute/html/attribute.erb +2 -1
- data/yard_templates/api_doc/resource_attribute/html/attribute.erb +2 -1
- data/yard_templates/api_doc/sidebar/html/profile_list.erb +2 -1
- data/yard_templates/api_doc/sidebar/html/serializer_list.erb +2 -1
- data.tar.gz.sig +0 -0
- metadata +34 -36
- metadata.gz.sig +0 -0
- data/lib/shaf/api_doc/comment.rb +0 -27
- data/lib/shaf/api_doc/document.rb +0 -137
- data/lib/shaf/api_doc/link_relations.rb +0 -77
- data/lib/shaf/middleware.rb +0 -1
- 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 | 
            -
                     | 
| 28 | 
            -
                    @controllers << controller
         | 
| 70 | 
            +
                    controllers << controller
         | 
| 29 71 | 
             
                  end
         | 
| 30 72 |  | 
| 31 73 | 
             
                  def routes
         | 
| 32 | 
            -
                     | 
| 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 | 
            -
                   | 
| 85 | 
            +
                  def controllers
         | 
| 86 | 
            +
                    @controllers ||= []
         | 
| 87 | 
            +
                  end
         | 
| 45 88 |  | 
| 46 89 | 
             
                  def init_routes
         | 
| 47 | 
            -
                     | 
| 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|  | 
| 93 | 
            +
                    controllers.each { |controller| init(controller, routes) }
         | 
| 94 | 
            +
                    routes
         | 
| 51 95 | 
             
                  end
         | 
| 52 96 |  | 
| 53 | 
            -
                  def  | 
| 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 | 
            -
                   | 
| 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  | 
| 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)
         | 
    
        data/lib/shaf/tasks.rb
    CHANGED
    
    
    
        data/lib/shaf/upgrade/package.rb
    CHANGED
    
    | @@ -236,18 +236,16 @@ module Shaf | |
| 236 236 | 
             
                    replacement = params[:replace]
         | 
| 237 237 |  | 
| 238 238 | 
             
                    changed = false
         | 
| 239 | 
            -
                     | 
| 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 | 
            -
                         | 
| 243 | 
            +
                        new_content << line
         | 
| 243 244 | 
             
                      end
         | 
| 244 | 
            -
                       | 
| 245 | 
            +
                      new_content
         | 
| 245 246 | 
             
                    end
         | 
| 246 247 |  | 
| 247 | 
            -
                     | 
| 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  | 
| 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|  | 
| 112 | 
            +
                    Zlib::GzipReader.open(zip_file) { |content| content.read }
         | 
| 113 113 | 
             
                  end
         | 
| 114 114 |  | 
| 115 115 | 
             
                  private
         | 
    
        data/lib/shaf/version.rb
    CHANGED
    
    
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'shaf/ | 
| 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 | 
            -
                     | 
| 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"
         | 
| @@ -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
         | 
| @@ -4,4 +4,7 @@ require 'minitest/autorun' | |
| 4 4 | 
             
            require 'minitest/hooks'
         | 
| 5 5 | 
             
            require 'shaf/spec'
         | 
| 6 6 |  | 
| 7 | 
            -
            Shaf:: | 
| 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 | | 
| 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 | | 
| 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 | | 
| 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 | | 
| 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:  | 
| 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 | 
            -
               | 
| 15 | 
            -
               | 
| 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 | 
            -
               | 
| 26 | 
            -
               | 
| 27 | 
            -
               | 
| 28 | 
            -
               | 
| 29 | 
            -
               | 
| 30 | 
            -
               | 
| 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:  | 
| 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. | 
| 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. | 
| 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. | 
| 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 | 
    
        data/lib/shaf/api_doc/comment.rb
    DELETED
    
    | @@ -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
         |