Permalink
Browse files

Initial import

  • Loading branch information...
0 parents commit 69740d67da948107cfc008421ef60d2894fefcb4 @mattt committed Apr 28, 2012
Showing with 200 additions and 0 deletions.
  1. +19 −0 LICENSE
  2. +38 −0 README.md
  3. +4 −0 example/Gemfile
  4. +24 −0 example/Gemfile.lock
  5. +1 −0 example/Procfile
  6. +43 −0 example/app.rb
  7. +3 −0 example/config.ru
  8. +68 −0 lib/sinatra/param.rb
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Mattt Thompson (http://mattt.me/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,38 @@
+# sinatra-param
+_Parameter Validation and Typecasting for Sinatra_
+
+## Example
+
+``` ruby
+class App < Sinatra::Base
+ helpers Sinatra::Param
+
+ before do
+ content_type :json
+ end
+
+ # GET /messages
+ # GET /messages?sort=name&order=ASC
+ get '/messages' do
+ param :sort, String, default: "name"
+ param :order, String, in: ["ASC", "DESC"], transform: :upcase, default: "ASC"
+
+ {
+ sort: params[:sort],
+ order: params[:order]
+ }.to_json
+ end
+end
+```
+
+## Contact
+
+Mattt Thompson
+
+- http://github.com/mattt
+- http://twitter.com/mattt
+- m@mattt.me
+
+## License
+
+sinatra-param is available under the MIT license. See the LICENSE file for more info.
@@ -0,0 +1,4 @@
+source :rubygems
+
+gem 'sinatra'
+gem 'thin'
@@ -0,0 +1,24 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ daemons (1.1.8)
+ eventmachine (0.12.10)
+ rack (1.4.1)
+ rack-protection (1.2.0)
+ rack
+ sinatra (1.3.2)
+ rack (~> 1.3, >= 1.3.6)
+ rack-protection (~> 1.2)
+ tilt (~> 1.3, >= 1.3.3)
+ thin (1.3.1)
+ daemons (>= 1.0.9)
+ eventmachine (>= 0.12.6)
+ rack (>= 1.0.0)
+ tilt (1.3.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ sinatra
+ thin
@@ -0,0 +1 @@
+web: bundle exec thin start -p $PORT
@@ -0,0 +1,43 @@
+require 'sinatra/base'
+require 'json'
+
+require '../lib/sinatra/param'
+
+class App < Sinatra::Base
+ helpers Sinatra::Param
+
+ before do
+ content_type :json
+ end
+
+ # GET /messages
+ # GET /messages?sort=name&order=ASC
+ get '/messages' do
+ param :sort, String, default: "name"
+ param :order, String, in: ["ASC", "DESC"], transform: :upcase, default: "ASC"
+
+ {
+ sort: params[:sort],
+ order: params[:order]
+ }.to_json
+ end
+
+ # GET /messages/1,2,3,4,5
+ get '/messages/:ids' do
+ param :ids, Array, required: true
+
+ {
+ ids: params[:ids]
+ }.to_json
+ end
+
+ # POST /messages/1/response
+ post '/messages/:id/response' do
+ param :message, String, max: 1024, required: true
+
+ {
+ message: params[:message]
+ }.to_json
+ end
+end
+
@@ -0,0 +1,3 @@
+require './app'
+
+run App
@@ -0,0 +1,68 @@
+module Sinatra
+ module Param
+ VERSION = "0.0.1"
+
+ class InvalidParameterError < StandardError; end
+
+ def param(name, type, options = {})
+ begin
+ params[name] = coerce(params[name], type, options) || options[:default]
+ params[name] = options[:transform].to_proc.call(params[name]) if options[:transform]
+ validate!(params[name], options)
+ rescue
+ error = "Invalid parameter, #{name}"
+ if content_type.match(mime_type(:json))
+ error = {message: error}.to_json
+ end
+
+ halt 406, error
+ end
+ end
+
+ private
+
+ def coerce(param, type, options = {})
+ return nil if param.nil?
+ return Integer(param) if type == Integer
+ return Float(param) if type == Float
+ return String(param) if type == String
+ return Array(param.split(options[:delimiter] || ",")) if type == Array
+ return Hash[param.split(options[:delimiter] || ",").map{|c| c.split(options[:separator] || ":")}] if type == Hash
+ return ((/(false|f|no|n|0)$/i === param) ? false : (/(true|t|yes|y|1)$/i === param) ? true : nil) if type == Boolean
+ return nil
+ end
+
+ def validate!(param, options)
+ options.each do |key, value|
+ case key
+ when :required
+ raise InvalidParameterError if value && param.nil?
+ when :blank
+ raise InvalidParameterError if !value && case param
+ when String
+ !(/\S/ === param)
+ when Array, Hash
+ param.empty?
+ else
+ param.nil?
+ end
+ when :is
+ raise InvalidParameterError unless value === param
+ when :in, :within, :range
+ raise InvalidParameterError unless case value
+ when Range
+ value.include?(param)
+ else
+ Array(value).include?(param)
+ end
+ when :min
+ raise InvalidParameterError unless value <= param
+ when :max
+ raise InvalidParameterError unless value >= param
+ end
+ end
+ end
+ end
+
+ helpers Param
+end

0 comments on commit 69740d6

Please sign in to comment.