-
1
require 'sinatra/base'
-
1
require 'sinatra/param/version'
-
1
require 'date'
-
1
require 'time'
-
-
1
module Sinatra
-
1
module Param
-
1
Boolean = :boolean
-
-
1
class InvalidParameterError < StandardError
-
1
attr_accessor :param, :options
-
end
-
-
1
def param(name, type, options = {})
-
213
name = name.to_s
-
213
applicable_params = @applicable_params || params
-
-
213
return unless applicable_params.member?(name) || options.has_key?(:default) ||
-
options[:required]
-
-
147
begin
-
147
applicable_params[name] = coerce(applicable_params[name], type, options)
-
applicable_params[name] = (options[:default].call if
-
8
options[:default].respond_to?(:call)) ||
-
141
options[:default] if applicable_params[name].nil? && options.has_key?(:default)
-
-
applicable_params[name] = options[:transform].to_proc.call(applicable_params[name]) if
-
141
applicable_params[name] && options[:transform]
-
-
141
validate!(applicable_params[name], options)
-
-
119
if block_given?
-
11
if type != Hash
-
1
raise Sinatra::Param::InvalidParameterError.new(
-
'Only the Hash parameter validation can use sub hash validation method')
-
end
-
10
original_applicable_params = @applicable_params
-
10
original_parent_key_name = @parent_key_name
-
10
@applicable_params = applicable_params[name]
-
10
@parent_key_name = formatted_params(@parent_key_name, name)
-
-
10
yield
-
-
5
@applicable_params = original_applicable_params
-
5
@parent_key_name = original_parent_key_name
-
end
-
-
113
applicable_params[name]
-
29
rescue InvalidParameterError => exception
-
29
exception_name = formatted_params(@parent_key_name, name)
-
29
if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
-
1
exception.param = exception_name
-
1
exception.options = options
-
1
raise exception
-
end
-
-
28
error = options[:message] || exception.to_s
-
-
28
if content_type and content_type.match(mime_type(:json))
-
28
error = { message: error, errors: { exception_name => exception.message } }.to_json
-
end
-
-
28
halt 400, error
-
end
-
end
-
-
1
def one_of(*args)
-
19
options = args.last.is_a?(Hash) ? args.pop : {}
-
19
names = args.collect(&:to_s)
-
19
applicable_params = @applicable_params || params
-
-
19
return unless names.length >= 2
-
-
15
begin
-
15
validate_one_of!(applicable_params, names, options)
-
6
rescue InvalidParameterError => exception
-
6
if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
-
1
exception.param, exception.options = names, options
-
1
raise exception
-
end
-
-
5
error = "Invalid parameters #{formatted_params(@parent_key_name, names)}"
-
5
if content_type && content_type.match(mime_type(:json))
-
5
error = { message: error, errors: { names => exception.message } }.to_json
-
end
-
-
5
halt 400, error
-
end
-
end
-
-
1
def any_of(*args)
-
10
options = args.last.is_a?(Hash) ? args.pop : {}
-
10
names = args.collect(&:to_s)
-
10
applicable_params = @applicable_params || params
-
-
10
return unless names.length >= 2
-
-
10
begin
-
10
validate_any_of!(applicable_params, names, options)
-
3
rescue InvalidParameterError => exception
-
3
if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
-
1
exception.param, exception.options = names, options
-
1
raise exception
-
end
-
-
2
formatted_params = formatted_params(@parent_key_name, names)
-
2
error = "Invalid parameters #{formatted_params}"
-
2
if content_type and content_type.match(mime_type(:json))
-
2
error = { message: error, errors: { formatted_params => exception.message } }.to_json
-
end
-
-
2
halt 400, error
-
end
-
end
-
-
1
def all_or_none_of(*args)
-
5
options = args.last.is_a?(Hash) ? args.pop : {}
-
5
names = args.collect(&:to_s)
-
-
5
begin
-
5
validate_all_or_none_of!(params, names, options)
-
3
rescue InvalidParameterError => exception
-
3
if options[:raise] or (settings.raise_sinatra_param_exceptions rescue false)
-
exception.param, exception.options = names, options
-
raise exception
-
end
-
-
3
error = "Invalid parameters [#{names.join(', ')}]"
-
3
if content_type and content_type.match(mime_type(:json))
-
3
error = { message: error, errors: { names => exception.message } }.to_json
-
end
-
-
3
halt 400, error
-
end
-
end
-
-
1
private
-
-
1
def coerce(param, type, options = {})
-
147
begin
-
147
return nil if param.nil?
-
134
return param if (param.is_a?(type) rescue false)
-
57
return Integer(param) if type == Integer
-
42
return Float(param) if type == Float
-
40
return String(param) if type == String
-
38
return Date.parse(param) if type == Date
-
36
return Time.parse(param) if type == Time
-
34
return DateTime.parse(param) if type == DateTime
-
32
return coerce_array(param, options) if type == Array
-
return Hash[param.to_s.split(options[:delimiter] || ",")
-
33
.map { |c| c.split(options[:separator] || ":") }] if type == Hash
-
20
return (/(false|f|no|n|0)$/i === param.to_s ? false :
-
10
(/(true|t|yes|y|1)$/i === param.to_s ? true : nil)) if type == TrueClass ||
-
21
type == FalseClass || type == Boolean
-
return nil
-
6
rescue ArgumentError
-
6
raise InvalidParameterError, "'#{param}' is not a valid #{type}"
-
end
-
end
-
-
###
-
# Array is a special case, we should convert from Hash
-
# or convert to string before parsing.
-
1
def coerce_array(param, options = {})
-
6
return param if param.is_a? Array
-
6
return param.to_a if param.is_a? Hash
-
5
Array(param.to_s.split(options[:delimiter] || ','))
-
end
-
-
1
def validate!(param, options)
-
141
options.each do |key, value|
-
65
case key
-
when :required
-
12
raise InvalidParameterError, 'Parameter is required' if value && param.nil?
-
when :blank
-
raise InvalidParameterError, 'Parameter cannot be blank' if !value && case param
-
when String
-
1
!(/\S/ === param)
-
when Array, Hash
-
2
param.empty?
-
else
-
1
param.nil?
-
5
end
-
when :format
-
raise InvalidParameterError,
-
'Parameter must be a string if using the format validation' unless
-
3
param.kind_of?(String)
-
2
raise InvalidParameterError, "Parameter must match format #{value}" unless param =~ value
-
when :is
-
2
raise InvalidParameterError, "Parameter must be #{value}" unless param === value
-
when :in, :within, :range
-
raise InvalidParameterError, "Parameter must be within #{value}" unless param.nil? ||
-
case value
-
when Range
-
8
case param
-
when Array
-
10
param.all? { |element| value.include?(element) }
-
else
-
4
value.include?(param)
-
end
-
else
-
4
case param
-
when Array
-
2
(param - Array(value)).empty?
-
else
-
2
Array(value).include?(param)
-
end
-
13
end
-
when :min
-
2
raise InvalidParameterError, "Parameter cannot be less than #{value}" unless param.nil? || value <= param
-
when :max
-
2
raise InvalidParameterError, "Parameter cannot be greater than #{value}" unless param.nil? || value >= param
-
when :min_length
-
1
raise InvalidParameterError, "Parameter cannot have length less than #{value}" unless param.nil? || value <= param.length
-
when :max_length
-
3
raise InvalidParameterError, "Parameter cannot have length greater than #{value}" unless param.nil? || value >= param.length
-
end
-
end
-
end
-
-
1
def validate_one_of!(params, names, options)
-
55
if names.count{|name| present?(params[name])} > 1
-
6
raise InvalidParameterError, "Only one of #{formatted_params(@parent_key_name, names)} is allowed"
-
end
-
end
-
-
1
def validate_any_of!(params, names, options)
-
40
if names.count{|name| present?(params[name])} < 1
-
3
raise InvalidParameterError, "One of parameters #{formatted_params(@parent_key_name, names)} is required"
-
end
-
end
-
-
1
def validate_all_or_none_of!(params, names, options)
-
20
present_count = names.count{|name| present?(params[name])}
-
5
raise InvalidParameterError, "All or none of parameters [#{names.join(', ')}] are required" if present_count > 0 and present_count != names.length
-
end
-
-
# ActiveSupport #present? and #blank? without patching Object
-
1
def present?(object)
-
85
!blank?(object)
-
end
-
-
1
def blank?(object)
-
85
object.respond_to?(:empty?) ? object.empty? : !object
-
end
-
-
1
def formatted_params(parent_key, name)
-
55
if name.is_a?(Array)
-
16
name = "[#{name.join(', ')}]"
-
end
-
-
55
return parent_key ? "#{parent_key}[#{name}]" : name
-
end
-
end
-
-
1
helpers Param
-
end