superintendent 0.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 +7 -0
- data/.gitignore +32 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +20 -0
- data/Rakefile +10 -0
- data/lib/superintendent.rb +6 -0
- data/lib/superintendent/initializer/register_json_api_mime_type.rb +10 -0
- data/lib/superintendent/request/bouncer.rb +79 -0
- data/lib/superintendent/request/id.rb +30 -0
- data/lib/superintendent/request/params_case_translator.rb +36 -0
- data/lib/superintendent/request/validator.rb +117 -0
- data/lib/superintendent/version.rb +3 -0
- data/superintendent.gemspec +32 -0
- metadata +235 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: a05a8e02df98ffee0c7c0d1e5e02a92962693e3c
         | 
| 4 | 
            +
              data.tar.gz: 848d649d35c92c1c30a05cd27f0698b9570916f7
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: a75a67e28f8c57f0cefb94954de44f35cd7b6e5cc3d8f38d6058d43274284efaefb879987cd6f276a715bd9e9b1a79b13941831277accff8a701d240d1498a97
         | 
| 7 | 
            +
              data.tar.gz: 2c7fd86673ebfa071147e8b849ed65976028dc4da96932c5b95c47ea6274515f869817dc1daf4d0429b4cc82896239ffe863562bc8234b73486295e794e81585
         | 
    
        data/.gitignore
    ADDED
    
    | @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            *.gem
         | 
| 2 | 
            +
            *.rbc
         | 
| 3 | 
            +
            /.config
         | 
| 4 | 
            +
            /coverage/
         | 
| 5 | 
            +
            /InstalledFiles
         | 
| 6 | 
            +
            /pkg/
         | 
| 7 | 
            +
            /spec/reports/
         | 
| 8 | 
            +
            /test/tmp/
         | 
| 9 | 
            +
            /test/version_tmp/
         | 
| 10 | 
            +
            /tmp/
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ## Specific to RubyMotion:
         | 
| 13 | 
            +
            .dat*
         | 
| 14 | 
            +
            .repl_history
         | 
| 15 | 
            +
            build/
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## Documentation cache and generated files:
         | 
| 18 | 
            +
            /.yardoc/
         | 
| 19 | 
            +
            /_yardoc/
         | 
| 20 | 
            +
            /doc/
         | 
| 21 | 
            +
            /rdoc/
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## Environment normalisation:
         | 
| 24 | 
            +
            /.bundle/
         | 
| 25 | 
            +
            /lib/bundler/man/
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Gemfile.lock
         | 
| 28 | 
            +
            .ruby-version
         | 
| 29 | 
            +
            .ruby-gemset
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
         | 
| 32 | 
            +
            .rvmrc
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            The MIT License (MIT)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Copyright (c) 2015 Ben Mills
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 6 | 
            +
            of this software and associated documentation files (the "Software"), to deal
         | 
| 7 | 
            +
            in the Software without restriction, including without limitation the rights
         | 
| 8 | 
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         | 
| 9 | 
            +
            copies of the Software, and to permit persons to whom the Software is
         | 
| 10 | 
            +
            furnished to do so, subject to the following conditions:
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            The above copyright notice and this permission notice shall be included in
         | 
| 13 | 
            +
            all copies or substantial portions of the Software.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         | 
| 16 | 
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         | 
| 17 | 
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         | 
| 18 | 
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         | 
| 19 | 
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         | 
| 20 | 
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         | 
| 21 | 
            +
            THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            # Superintendent
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Middlewares to aid in building powerful JSON API applications.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Installation
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Add this line to your application's Gemfile:
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ```ruby
         | 
| 10 | 
            +
            gem 'superintendent'
         | 
| 11 | 
            +
            ```
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            And then execute:
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                $ bundle
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            Or install it yourself as:
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                $ gem install superintendent
         | 
| 20 | 
            +
             | 
    
        data/Rakefile
    ADDED
    
    
| @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            require 'action_dispatch/http/request'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Superintendent
         | 
| 4 | 
            +
              module Request
         | 
| 5 | 
            +
                class Bouncer
         | 
| 6 | 
            +
                  DEFAULT_OPTS = {
         | 
| 7 | 
            +
                    required_headers: [],
         | 
| 8 | 
            +
                    supported_content_types: [
         | 
| 9 | 
            +
                      'application/json',
         | 
| 10 | 
            +
                      'application/x-www-form-urlencoded'
         | 
| 11 | 
            +
                    ]
         | 
| 12 | 
            +
                  }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def initialize(app, opts={})
         | 
| 15 | 
            +
                    @app, @options = app, DEFAULT_OPTS.merge(opts)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def call(env)
         | 
| 19 | 
            +
                    @request = ActionDispatch::Request.new(env)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    if required_keys_missing?
         | 
| 22 | 
            +
                      return respond_400(
         | 
| 23 | 
            +
                        {
         | 
| 24 | 
            +
                          code: 'headers-missing',
         | 
| 25 | 
            +
                          title: 'Headers missing',
         | 
| 26 | 
            +
                          detail: 'Required headers were not present in the request'
         | 
| 27 | 
            +
                        }
         | 
| 28 | 
            +
                      )
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    if %w[POST PUT PATCH].include? @request.request_method
         | 
| 32 | 
            +
                      if unsupported_content_type?
         | 
| 33 | 
            +
                        return respond_400(
         | 
| 34 | 
            +
                          {
         | 
| 35 | 
            +
                            code: 'content-type-unsupported',
         | 
| 36 | 
            +
                            title: 'Request content-type is unsupported',
         | 
| 37 | 
            +
                            detail: "#{@request.content_type} is not a supported content-type"
         | 
| 38 | 
            +
                          }
         | 
| 39 | 
            +
                        )
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    @app.call(env)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  private
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def unsupported_content_type?
         | 
| 49 | 
            +
                    content_type = @request.content_type
         | 
| 50 | 
            +
                    return false if content_type.nil? || content_type.empty?
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    !@options[:supported_content_types].include? content_type
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def required_keys_missing?
         | 
| 56 | 
            +
                    @options[:required_headers].any? { |key| !@request.headers.include?(key) }
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def respond_400(attributes)
         | 
| 60 | 
            +
                    [400,
         | 
| 61 | 
            +
                     {'Content-Type' => 'application/vnd.api+json'},
         | 
| 62 | 
            +
                     [
         | 
| 63 | 
            +
                       {
         | 
| 64 | 
            +
                         errors: [
         | 
| 65 | 
            +
                           {
         | 
| 66 | 
            +
                             attributes: {
         | 
| 67 | 
            +
                               id: @request.headers[Id::X_REQUEST_ID],
         | 
| 68 | 
            +
                               status: 400
         | 
| 69 | 
            +
                             }.merge(attributes),
         | 
| 70 | 
            +
                             type: 'errors'
         | 
| 71 | 
            +
                           }
         | 
| 72 | 
            +
                         ]
         | 
| 73 | 
            +
                       }.to_json
         | 
| 74 | 
            +
                     ]
         | 
| 75 | 
            +
                    ]
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require 'securerandom'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Superintendent::Request
         | 
| 4 | 
            +
              class Id
         | 
| 5 | 
            +
                X_REQUEST_ID = 'X-Request-Id'.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(app)
         | 
| 8 | 
            +
                  @app = app
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def call(env)
         | 
| 12 | 
            +
                  request_id = make_request_id(env['HTTP_X_REQUEST_ID'])
         | 
| 13 | 
            +
                  @app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = request_id }
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                private
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def make_request_id(request_id)
         | 
| 19 | 
            +
                  if request_id && ! request_id.empty?
         | 
| 20 | 
            +
                    request_id.gsub(/[^\w\-]/, "".freeze)[0..255]
         | 
| 21 | 
            +
                  else
         | 
| 22 | 
            +
                    internal_request_id
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def internal_request_id
         | 
| 27 | 
            +
                  "OHM#{SecureRandom.uuid.gsub!('-', '')}"
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            module Superintendent::Request
         | 
| 2 | 
            +
              class ParamsCaseTranslator
         | 
| 3 | 
            +
                DATA_CASE = 'HTTP_X_API_DATA_CASE'.freeze
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(app, opts={})
         | 
| 6 | 
            +
                  @app, @options = app, opts
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def call(env)
         | 
| 10 | 
            +
                  request = ActionDispatch::Request.new(env)
         | 
| 11 | 
            +
                  if ['POST', 'PUT', 'PATCH'].include? request.method
         | 
| 12 | 
            +
                    if env.has_key?(DATA_CASE) && env[DATA_CASE] == 'camel-lower'
         | 
| 13 | 
            +
                      request.request_parameters = underscored_keys(request.request_parameters)
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  @app.call(env)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                private
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def underscored_key(k)
         | 
| 22 | 
            +
                  k.to_s.underscore
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def underscored_keys(value)
         | 
| 26 | 
            +
                  case value
         | 
| 27 | 
            +
                  when Array
         | 
| 28 | 
            +
                    value.map { |v| underscored_keys(v) }
         | 
| 29 | 
            +
                  when Hash
         | 
| 30 | 
            +
                    Hash[value.map { |k, v| [underscored_key(k), underscored_keys(v)] }]
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    value
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| @@ -0,0 +1,117 @@ | |
| 1 | 
            +
            require 'json-schema'
         | 
| 2 | 
            +
            require 'action_dispatch/http/mime_type'
         | 
| 3 | 
            +
            require 'action_dispatch/http/parameters'
         | 
| 4 | 
            +
            require 'action_dispatch/http/request'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Superintendent::Request
         | 
| 7 | 
            +
              class Validator
         | 
| 8 | 
            +
                FORM_METHOD_ACTIONS = {
         | 
| 9 | 
            +
                  'POST' => 'create',
         | 
| 10 | 
            +
                  'PATCH' => 'update',
         | 
| 11 | 
            +
                  'PUT' => 'update'
         | 
| 12 | 
            +
                }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                DEFAULT_OPTIONS = {
         | 
| 15 | 
            +
                  :monitored_content_types => ['application/json']
         | 
| 16 | 
            +
                }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                JSON_API_CONTENT_TYPE = 'application/vnd.api+json'.freeze
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def initialize(app, opts={})
         | 
| 21 | 
            +
                  @app, @options = app, DEFAULT_OPTIONS.merge(opts)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def call(env)
         | 
| 25 | 
            +
                  request = ActionDispatch::Request.new(env)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # Only manage requests for the selected Mime Types and
         | 
| 28 | 
            +
                  # FORM_METHOD_ACTIONS.
         | 
| 29 | 
            +
                  if @options[:monitored_content_types].include?(request.content_type) &&
         | 
| 30 | 
            +
                    FORM_METHOD_ACTIONS.has_key?(request.request_method)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    request_data = request.request_parameters
         | 
| 33 | 
            +
                    resource = requested_resource(request.path_info)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    begin
         | 
| 36 | 
            +
                      forms = "#{resource}Form".constantize
         | 
| 37 | 
            +
                      form = form_for_method(forms, request.request_method)
         | 
| 38 | 
            +
                    rescue NameError => e
         | 
| 39 | 
            +
                      return respond_404 # Return a 404 if no form was found.
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    errors = JSON::Validator.fully_validate(
         | 
| 43 | 
            +
                      form, request_data, { errors_as_objects: true })
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    if ! errors.empty?
         | 
| 46 | 
            +
                      return respond_400(serialize_errors(request.headers[Id::X_REQUEST_ID], errors))
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                    drop_extra_params!(form, request_data) unless request_data.blank?
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  @app.call(env)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                private
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                # Parameters that are not in the form are removed from the request so they
         | 
| 57 | 
            +
                # never reach the controller.
         | 
| 58 | 
            +
                def drop_extra_params!(form, data)
         | 
| 59 | 
            +
                  form_data = form['properties']['data']['properties']
         | 
| 60 | 
            +
                  allowed_params = form_data['attributes']['properties'].keys rescue nil
         | 
| 61 | 
            +
                  allowed_params.nil? ? nil : data['data']['attributes'].slice!(*allowed_params)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def form_for_method(forms, request_method)
         | 
| 65 | 
            +
                  forms.send(FORM_METHOD_ACTIONS[request_method]).with_indifferent_access
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                # Adjust the errors returned from the schema validator so they can be
         | 
| 69 | 
            +
                # reused in the serialized error response.
         | 
| 70 | 
            +
                def adjust_errors(form_errors)
         | 
| 71 | 
            +
                  form_errors.each do |e|
         | 
| 72 | 
            +
                    case e[:failed_attribute]
         | 
| 73 | 
            +
                    when 'Required'
         | 
| 74 | 
            +
                      e[:message].gsub!("The property '#/'", 'The request')
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                    e[:message].gsub!("The property '#/", "The property '")
         | 
| 77 | 
            +
                    e[:message] = e[:message][/.+?(?= in schema)/]
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                def serialize_errors(request_id, form_errors)
         | 
| 82 | 
            +
                  form_errors = adjust_errors(form_errors)
         | 
| 83 | 
            +
                  errors = []
         | 
| 84 | 
            +
                  form_errors.each do |e|
         | 
| 85 | 
            +
                    error = {
         | 
| 86 | 
            +
                      id: request_id,
         | 
| 87 | 
            +
                      status: 400,
         | 
| 88 | 
            +
                      code: e[:failed_attribute].underscore.dasherize,
         | 
| 89 | 
            +
                      title: e[:failed_attribute],
         | 
| 90 | 
            +
                      detail: e[:message]
         | 
| 91 | 
            +
                    }
         | 
| 92 | 
            +
                    errors << { attributes: error, type: 'errors' }
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                  JSON.pretty_generate({errors: errors})
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                # Determine the requested resource based on the requested endpoint
         | 
| 98 | 
            +
                def requested_resource(request_path)
         | 
| 99 | 
            +
                  parts = request_path.split('/')
         | 
| 100 | 
            +
                  # if the last part is an ID, return the part before it, the resource.
         | 
| 101 | 
            +
                  if (parts[-1]=~/(\d+|[A-Z]{2}[a-zA-Z0-9]{32})/)
         | 
| 102 | 
            +
                    resource = parts[-2]
         | 
| 103 | 
            +
                  else
         | 
| 104 | 
            +
                    resource = parts[-1]
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                  resource.singularize.classify
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                def respond_400(errors)
         | 
| 110 | 
            +
                  [400, {'Content-Type' => JSON_API_CONTENT_TYPE}, [errors]]
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                def respond_404
         | 
| 114 | 
            +
                  [404, {'Content-Type' => JSON_API_CONTENT_TYPE}, ['']]
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'superintendent/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "superintendent"
         | 
| 8 | 
            +
              spec.version       = Superintendent::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Ben Mills"]
         | 
| 10 | 
            +
              spec.email         = ["ben@unfiniti.com"]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              spec.summary       = "Middlewares to aid in building powerful JSON API applications."
         | 
| 13 | 
            +
              spec.description   = "Middlewares to aid in building powerful JSON API applications."
         | 
| 14 | 
            +
              spec.homepage      = "https://github.com/remear/superintendent"
         | 
| 15 | 
            +
              spec.license       = "MIT"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
         | 
| 18 | 
            +
              spec.require_paths = ["lib"]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              spec.add_runtime_dependency 'rack', '>= 2.0.0.alpha', '< 3.0'
         | 
| 21 | 
            +
              spec.add_runtime_dependency 'json-schema', '~> 2.5'
         | 
| 22 | 
            +
              spec.add_runtime_dependency 'activesupport', '>= 5.0.0.beta1', '< 5.1'
         | 
| 23 | 
            +
              spec.add_runtime_dependency 'actionpack', '>= 5.0.0.beta1', '< 5.1'
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              spec.add_development_dependency 'bundler', '~> 1.10'
         | 
| 26 | 
            +
              spec.add_development_dependency "rake", '>= 10.4', '< 12.0'
         | 
| 27 | 
            +
              spec.add_development_dependency 'minitest', '~> 5.8'
         | 
| 28 | 
            +
              spec.add_development_dependency 'minitest-reporters'
         | 
| 29 | 
            +
              spec.add_development_dependency 'simplecov', '~> 0.10'
         | 
| 30 | 
            +
              spec.add_development_dependency 'mocha', '~> 1.1'
         | 
| 31 | 
            +
              spec.add_development_dependency 'pry-byebug'
         | 
| 32 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,235 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: superintendent
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Ben Mills
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2016-08-09 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: rack
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: 2.0.0.alpha
         | 
| 20 | 
            +
                - - "<"
         | 
| 21 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 22 | 
            +
                    version: '3.0'
         | 
| 23 | 
            +
              type: :runtime
         | 
| 24 | 
            +
              prerelease: false
         | 
| 25 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 26 | 
            +
                requirements:
         | 
| 27 | 
            +
                - - ">="
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            +
                    version: 2.0.0.alpha
         | 
| 30 | 
            +
                - - "<"
         | 
| 31 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            +
                    version: '3.0'
         | 
| 33 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 34 | 
            +
              name: json-schema
         | 
| 35 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 36 | 
            +
                requirements:
         | 
| 37 | 
            +
                - - "~>"
         | 
| 38 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 39 | 
            +
                    version: '2.5'
         | 
| 40 | 
            +
              type: :runtime
         | 
| 41 | 
            +
              prerelease: false
         | 
| 42 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 43 | 
            +
                requirements:
         | 
| 44 | 
            +
                - - "~>"
         | 
| 45 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 46 | 
            +
                    version: '2.5'
         | 
| 47 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 48 | 
            +
              name: activesupport
         | 
| 49 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 50 | 
            +
                requirements:
         | 
| 51 | 
            +
                - - ">="
         | 
| 52 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 53 | 
            +
                    version: 5.0.0.beta1
         | 
| 54 | 
            +
                - - "<"
         | 
| 55 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 56 | 
            +
                    version: '5.1'
         | 
| 57 | 
            +
              type: :runtime
         | 
| 58 | 
            +
              prerelease: false
         | 
| 59 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 60 | 
            +
                requirements:
         | 
| 61 | 
            +
                - - ">="
         | 
| 62 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 63 | 
            +
                    version: 5.0.0.beta1
         | 
| 64 | 
            +
                - - "<"
         | 
| 65 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 66 | 
            +
                    version: '5.1'
         | 
| 67 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 68 | 
            +
              name: actionpack
         | 
| 69 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 70 | 
            +
                requirements:
         | 
| 71 | 
            +
                - - ">="
         | 
| 72 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 73 | 
            +
                    version: 5.0.0.beta1
         | 
| 74 | 
            +
                - - "<"
         | 
| 75 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 76 | 
            +
                    version: '5.1'
         | 
| 77 | 
            +
              type: :runtime
         | 
| 78 | 
            +
              prerelease: false
         | 
| 79 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 80 | 
            +
                requirements:
         | 
| 81 | 
            +
                - - ">="
         | 
| 82 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 83 | 
            +
                    version: 5.0.0.beta1
         | 
| 84 | 
            +
                - - "<"
         | 
| 85 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 86 | 
            +
                    version: '5.1'
         | 
| 87 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 88 | 
            +
              name: bundler
         | 
| 89 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 90 | 
            +
                requirements:
         | 
| 91 | 
            +
                - - "~>"
         | 
| 92 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 93 | 
            +
                    version: '1.10'
         | 
| 94 | 
            +
              type: :development
         | 
| 95 | 
            +
              prerelease: false
         | 
| 96 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 97 | 
            +
                requirements:
         | 
| 98 | 
            +
                - - "~>"
         | 
| 99 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 100 | 
            +
                    version: '1.10'
         | 
| 101 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 102 | 
            +
              name: rake
         | 
| 103 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 104 | 
            +
                requirements:
         | 
| 105 | 
            +
                - - ">="
         | 
| 106 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 107 | 
            +
                    version: '10.4'
         | 
| 108 | 
            +
                - - "<"
         | 
| 109 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            +
                    version: '12.0'
         | 
| 111 | 
            +
              type: :development
         | 
| 112 | 
            +
              prerelease: false
         | 
| 113 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '10.4'
         | 
| 118 | 
            +
                - - "<"
         | 
| 119 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 120 | 
            +
                    version: '12.0'
         | 
| 121 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 122 | 
            +
              name: minitest
         | 
| 123 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 124 | 
            +
                requirements:
         | 
| 125 | 
            +
                - - "~>"
         | 
| 126 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 127 | 
            +
                    version: '5.8'
         | 
| 128 | 
            +
              type: :development
         | 
| 129 | 
            +
              prerelease: false
         | 
| 130 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 131 | 
            +
                requirements:
         | 
| 132 | 
            +
                - - "~>"
         | 
| 133 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 134 | 
            +
                    version: '5.8'
         | 
| 135 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 136 | 
            +
              name: minitest-reporters
         | 
| 137 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 138 | 
            +
                requirements:
         | 
| 139 | 
            +
                - - ">="
         | 
| 140 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 141 | 
            +
                    version: '0'
         | 
| 142 | 
            +
              type: :development
         | 
| 143 | 
            +
              prerelease: false
         | 
| 144 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 145 | 
            +
                requirements:
         | 
| 146 | 
            +
                - - ">="
         | 
| 147 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 148 | 
            +
                    version: '0'
         | 
| 149 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 150 | 
            +
              name: simplecov
         | 
| 151 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 152 | 
            +
                requirements:
         | 
| 153 | 
            +
                - - "~>"
         | 
| 154 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 155 | 
            +
                    version: '0.10'
         | 
| 156 | 
            +
              type: :development
         | 
| 157 | 
            +
              prerelease: false
         | 
| 158 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 159 | 
            +
                requirements:
         | 
| 160 | 
            +
                - - "~>"
         | 
| 161 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 162 | 
            +
                    version: '0.10'
         | 
| 163 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 164 | 
            +
              name: mocha
         | 
| 165 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 166 | 
            +
                requirements:
         | 
| 167 | 
            +
                - - "~>"
         | 
| 168 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 169 | 
            +
                    version: '1.1'
         | 
| 170 | 
            +
              type: :development
         | 
| 171 | 
            +
              prerelease: false
         | 
| 172 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 173 | 
            +
                requirements:
         | 
| 174 | 
            +
                - - "~>"
         | 
| 175 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 176 | 
            +
                    version: '1.1'
         | 
| 177 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 178 | 
            +
              name: pry-byebug
         | 
| 179 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 180 | 
            +
                requirements:
         | 
| 181 | 
            +
                - - ">="
         | 
| 182 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 183 | 
            +
                    version: '0'
         | 
| 184 | 
            +
              type: :development
         | 
| 185 | 
            +
              prerelease: false
         | 
| 186 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 187 | 
            +
                requirements:
         | 
| 188 | 
            +
                - - ">="
         | 
| 189 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 190 | 
            +
                    version: '0'
         | 
| 191 | 
            +
            description: Middlewares to aid in building powerful JSON API applications.
         | 
| 192 | 
            +
            email:
         | 
| 193 | 
            +
            - ben@unfiniti.com
         | 
| 194 | 
            +
            executables: []
         | 
| 195 | 
            +
            extensions: []
         | 
| 196 | 
            +
            extra_rdoc_files: []
         | 
| 197 | 
            +
            files:
         | 
| 198 | 
            +
            - ".gitignore"
         | 
| 199 | 
            +
            - Gemfile
         | 
| 200 | 
            +
            - LICENSE.txt
         | 
| 201 | 
            +
            - README.md
         | 
| 202 | 
            +
            - Rakefile
         | 
| 203 | 
            +
            - lib/superintendent.rb
         | 
| 204 | 
            +
            - lib/superintendent/initializer/register_json_api_mime_type.rb
         | 
| 205 | 
            +
            - lib/superintendent/request/bouncer.rb
         | 
| 206 | 
            +
            - lib/superintendent/request/id.rb
         | 
| 207 | 
            +
            - lib/superintendent/request/params_case_translator.rb
         | 
| 208 | 
            +
            - lib/superintendent/request/validator.rb
         | 
| 209 | 
            +
            - lib/superintendent/version.rb
         | 
| 210 | 
            +
            - superintendent.gemspec
         | 
| 211 | 
            +
            homepage: https://github.com/remear/superintendent
         | 
| 212 | 
            +
            licenses:
         | 
| 213 | 
            +
            - MIT
         | 
| 214 | 
            +
            metadata: {}
         | 
| 215 | 
            +
            post_install_message: 
         | 
| 216 | 
            +
            rdoc_options: []
         | 
| 217 | 
            +
            require_paths:
         | 
| 218 | 
            +
            - lib
         | 
| 219 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 220 | 
            +
              requirements:
         | 
| 221 | 
            +
              - - ">="
         | 
| 222 | 
            +
                - !ruby/object:Gem::Version
         | 
| 223 | 
            +
                  version: '0'
         | 
| 224 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 225 | 
            +
              requirements:
         | 
| 226 | 
            +
              - - ">="
         | 
| 227 | 
            +
                - !ruby/object:Gem::Version
         | 
| 228 | 
            +
                  version: '0'
         | 
| 229 | 
            +
            requirements: []
         | 
| 230 | 
            +
            rubyforge_project: 
         | 
| 231 | 
            +
            rubygems_version: 2.6.6
         | 
| 232 | 
            +
            signing_key: 
         | 
| 233 | 
            +
            specification_version: 4
         | 
| 234 | 
            +
            summary: Middlewares to aid in building powerful JSON API applications.
         | 
| 235 | 
            +
            test_files: []
         |