explicit 0.2.1 → 0.2.4
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
- data/README.md +75 -67
- data/app/helpers/explicit/application_helper.rb +32 -0
- data/app/views/explicit/documentation/_attribute.html.erb +38 -0
- data/app/views/explicit/documentation/_page.html.erb +166 -0
- data/app/views/explicit/documentation/_request.html.erb +87 -0
- data/app/views/explicit/documentation/request/_examples.html.erb +50 -0
- data/app/views/explicit/documentation/type/_agreement.html.erb +7 -0
- data/app/views/explicit/documentation/type/_array.html.erb +3 -0
- data/app/views/explicit/documentation/type/_big_decimal.html.erb +4 -0
- data/app/views/explicit/documentation/type/_boolean.html.erb +7 -0
- data/app/views/explicit/documentation/type/_date_time_iso8601.html.erb +3 -0
- data/app/views/explicit/documentation/type/_date_time_posix.html.erb +3 -0
- data/app/views/explicit/documentation/type/_enum.html.erb +7 -0
- data/app/views/explicit/documentation/type/_file.html.erb +9 -0
- data/app/views/explicit/documentation/type/_hash.html.erb +4 -0
- data/app/views/explicit/documentation/type/_integer.html.erb +25 -0
- data/app/views/explicit/documentation/type/_one_of.html.erb +11 -0
- data/app/views/explicit/documentation/type/_record.html.erb +9 -0
- data/app/views/explicit/documentation/type/_string.html.erb +21 -0
- data/config/locales/en.yml +27 -11
- data/lib/explicit/configuration.rb +1 -1
- data/lib/explicit/documentation/builder.rb +80 -0
- data/lib/explicit/documentation/markdown.rb +2 -13
- data/lib/explicit/documentation/output/swagger.rb +176 -0
- data/lib/explicit/documentation/output/webpage.rb +31 -0
- data/lib/explicit/documentation/page/partial.rb +20 -0
- data/lib/explicit/documentation/page/request.rb +27 -0
- data/lib/explicit/documentation/section.rb +9 -0
- data/lib/explicit/documentation.rb +12 -145
- data/lib/explicit/request/example.rb +50 -1
- data/lib/explicit/request/invalid_params_error.rb +1 -3
- data/lib/explicit/request/invalid_response_error.rb +2 -15
- data/lib/explicit/request/route.rb +18 -0
- data/lib/explicit/request.rb +43 -24
- data/lib/explicit/test_helper/example_recorder.rb +7 -2
- data/lib/explicit/test_helper.rb +25 -7
- data/lib/explicit/type/agreement.rb +39 -0
- data/lib/explicit/type/array.rb +56 -0
- data/lib/explicit/type/big_decimal.rb +58 -0
- data/lib/explicit/type/boolean.rb +47 -0
- data/lib/explicit/type/date_time_iso8601.rb +41 -0
- data/lib/explicit/type/date_time_posix.rb +44 -0
- data/lib/explicit/type/enum.rb +41 -0
- data/lib/explicit/type/file.rb +60 -0
- data/lib/explicit/type/hash.rb +57 -0
- data/lib/explicit/type/integer.rb +79 -0
- data/lib/explicit/type/literal.rb +45 -0
- data/lib/explicit/type/modifiers/default.rb +24 -0
- data/lib/explicit/type/modifiers/description.rb +11 -0
- data/lib/explicit/type/modifiers/nilable.rb +19 -0
- data/lib/explicit/type/modifiers/param_location.rb +11 -0
- data/lib/explicit/type/one_of.rb +46 -0
- data/lib/explicit/type/record.rb +96 -0
- data/lib/explicit/type/string.rb +68 -0
- data/lib/explicit/type.rb +112 -0
- data/lib/explicit/version.rb +1 -1
- data/lib/explicit.rb +28 -18
- metadata +47 -25
- data/app/views/explicit/application/_documentation.html.erb +0 -136
- data/app/views/explicit/application/_request.html.erb +0 -37
- data/lib/explicit/documentation/property.rb +0 -19
- data/lib/explicit/spec/agreement.rb +0 -17
- data/lib/explicit/spec/array.rb +0 -28
- data/lib/explicit/spec/bigdecimal.rb +0 -27
- data/lib/explicit/spec/boolean.rb +0 -30
- data/lib/explicit/spec/date_time_iso8601.rb +0 -17
- data/lib/explicit/spec/date_time_posix.rb +0 -21
- data/lib/explicit/spec/default.rb +0 -20
- data/lib/explicit/spec/error.rb +0 -63
- data/lib/explicit/spec/hash.rb +0 -30
- data/lib/explicit/spec/inclusion.rb +0 -15
- data/lib/explicit/spec/integer.rb +0 -53
- data/lib/explicit/spec/literal.rb +0 -15
- data/lib/explicit/spec/nilable.rb +0 -15
- data/lib/explicit/spec/one_of.rb +0 -40
- data/lib/explicit/spec/record.rb +0 -33
- data/lib/explicit/spec/string.rb +0 -50
- data/lib/explicit/spec.rb +0 -72
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "time"
|
4
|
-
|
5
|
-
module Explicit::Spec::DateTimePosix
|
6
|
-
extend self
|
7
|
-
|
8
|
-
ERROR_INVALID = [:error, :date_time_posix].freeze
|
9
|
-
|
10
|
-
def call(value)
|
11
|
-
if !value.is_a?(::Integer) && !value.is_a?(::String)
|
12
|
-
return ERROR_INVALID
|
13
|
-
end
|
14
|
-
|
15
|
-
datetimeval = DateTime.strptime(value.to_s, "%s")
|
16
|
-
|
17
|
-
[:ok, datetimeval]
|
18
|
-
rescue Date::Error
|
19
|
-
ERROR_INVALID
|
20
|
-
end
|
21
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Default
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(defaultval, subspec)
|
7
|
-
subspec_validator = Explicit::Spec::build(subspec)
|
8
|
-
|
9
|
-
lambda do |value|
|
10
|
-
value =
|
11
|
-
if value.nil?
|
12
|
-
defaultval.respond_to?(:call) ? defaultval.call : defaultval
|
13
|
-
else
|
14
|
-
value
|
15
|
-
end
|
16
|
-
|
17
|
-
subspec_validator.call(value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/explicit/spec/error.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Error
|
4
|
-
extend self
|
5
|
-
|
6
|
-
RailsI18n = ->(error, **context) do
|
7
|
-
key = "explicit.errors.#{error}"
|
8
|
-
|
9
|
-
::I18n.t(key, **context)
|
10
|
-
end
|
11
|
-
|
12
|
-
def translate(error, translator = RailsI18n)
|
13
|
-
case error
|
14
|
-
in :agreement
|
15
|
-
translator.call(:agreement)
|
16
|
-
in [:array, index, suberr]
|
17
|
-
translator.call(:array, index:, error: translate(suberr, translator))
|
18
|
-
in :bigdecimal
|
19
|
-
translator.call(:bigdecimal)
|
20
|
-
in :boolean
|
21
|
-
translator.call(:boolean)
|
22
|
-
in :date_time_iso8601
|
23
|
-
translator.call(:date_time_iso8601)
|
24
|
-
in :date_time_posix
|
25
|
-
translator.call(:date_time_posix)
|
26
|
-
in :hash
|
27
|
-
translator.call(:hash)
|
28
|
-
in [:hash_key, key, suberr]
|
29
|
-
translator.call(:hash_key, key:, error: translate(suberr, translator))
|
30
|
-
in [:hash_value, key, suberr]
|
31
|
-
translator.call(:hash_value, key:, error: translate(suberr, translator))
|
32
|
-
in [:inclusion, values]
|
33
|
-
translator.call(:inclusion, values: values.inspect)
|
34
|
-
in :integer
|
35
|
-
translator.call(:integer)
|
36
|
-
in [:min, min]
|
37
|
-
translator.call(:min, min:)
|
38
|
-
in [:max, max]
|
39
|
-
translator.call(:max, max:)
|
40
|
-
in :negative
|
41
|
-
translator.call(:negative)
|
42
|
-
in :positive
|
43
|
-
translator.call(:positive)
|
44
|
-
in [:literal, value]
|
45
|
-
translator.call(:literal, value: value.inspect)
|
46
|
-
in [:one_of, *errors]
|
47
|
-
# TODO
|
48
|
-
errors.map { translate(_1, translator) }.join(" OR ")
|
49
|
-
in :string
|
50
|
-
translator.call(:string)
|
51
|
-
in :empty
|
52
|
-
translator.call(:empty)
|
53
|
-
in [:minlength, minlength]
|
54
|
-
translator.call(:minlength, minlength:)
|
55
|
-
in [:maxlength, maxlength]
|
56
|
-
translator.call(:maxlength, maxlength:)
|
57
|
-
in [:format, regex]
|
58
|
-
translator.call(:format, regex: regex.inspect)
|
59
|
-
in Hash
|
60
|
-
error.to_h { |attr_name, err| [attr_name, translate(err, translator)] }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/lib/explicit/spec/hash.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Hash
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(keyspec, valuespec, options)
|
7
|
-
keyspec_validator = Explicit::Spec.build(keyspec)
|
8
|
-
valuespec_validator = Explicit::Spec.build(valuespec)
|
9
|
-
|
10
|
-
lambda do |value|
|
11
|
-
return [:error, :hash] if !value.is_a?(::Hash)
|
12
|
-
return [:error, :empty] if value.empty? && !options[:empty]
|
13
|
-
|
14
|
-
validated_hash = {}
|
15
|
-
|
16
|
-
value.each do |key, value|
|
17
|
-
case [keyspec_validator.call(key), valuespec_validator.call(value)]
|
18
|
-
in [[:ok, validated_key], [:ok, validated_value]]
|
19
|
-
validated_hash[validated_key] = validated_value
|
20
|
-
in [[:error, err], _]
|
21
|
-
return [:error, [:hash_key, key, err]]
|
22
|
-
in [_, [:error, err]]
|
23
|
-
return [:error, [:hash_value, key, err]]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
[:ok, validated_hash]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Integer
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(options)
|
7
|
-
lambda do |value|
|
8
|
-
value =
|
9
|
-
if value.is_a?(::Integer)
|
10
|
-
value
|
11
|
-
elsif value.is_a?(::String) && options[:parse]
|
12
|
-
parse_from_string(value)
|
13
|
-
else
|
14
|
-
nil
|
15
|
-
end
|
16
|
-
|
17
|
-
return [:error, :integer] if value.nil?
|
18
|
-
|
19
|
-
if (min = options[:min]) && !validate_min(value, min)
|
20
|
-
return [:error, [:min, min]]
|
21
|
-
end
|
22
|
-
|
23
|
-
if (max = options[:max]) && !validate_max(value, max)
|
24
|
-
return [:error, [:max, max]]
|
25
|
-
end
|
26
|
-
|
27
|
-
if options[:negative] == false && value < 0
|
28
|
-
return [:error, :negative]
|
29
|
-
end
|
30
|
-
|
31
|
-
if options[:positive] == false && value > 0
|
32
|
-
return [:error, :positive]
|
33
|
-
end
|
34
|
-
|
35
|
-
[:ok, value]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def parse_from_string(value)
|
41
|
-
Integer(value)
|
42
|
-
rescue ::ArgumentError
|
43
|
-
nil
|
44
|
-
end
|
45
|
-
|
46
|
-
def validate_min(value, min)
|
47
|
-
value >= min
|
48
|
-
end
|
49
|
-
|
50
|
-
def validate_max(value, max)
|
51
|
-
value <= max
|
52
|
-
end
|
53
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Nilable
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(subspec)
|
7
|
-
subspec_validator = Explicit::Spec.build(subspec)
|
8
|
-
|
9
|
-
lambda do |value|
|
10
|
-
return [:ok, nil] if value.nil?
|
11
|
-
|
12
|
-
subspec_validator.call(value)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/explicit/spec/one_of.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::OneOf
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(subspecs)
|
7
|
-
subspec_validators = subspecs.map { Explicit::Spec.build(_1) }
|
8
|
-
|
9
|
-
errors = []
|
10
|
-
|
11
|
-
lambda do |value|
|
12
|
-
subspec_validators.each do |subspec_validator|
|
13
|
-
case subspec_validator.call(value)
|
14
|
-
in [:ok, validated_value]
|
15
|
-
return [:ok, validated_value]
|
16
|
-
in [:error, err]
|
17
|
-
errors << err
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
errors.each do |err|
|
22
|
-
if looks_like_at_least_one_attribute_matched?(value, err)
|
23
|
-
return [:error, err]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
[:error, [:one_of, *errors]]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
def looks_like_at_least_one_attribute_matched?(value, err)
|
33
|
-
return false if !value.is_a?(::Hash)
|
34
|
-
return false if !err.is_a?(::Hash)
|
35
|
-
|
36
|
-
keyset = value.keys - err.keys
|
37
|
-
|
38
|
-
keyset.empty?
|
39
|
-
end
|
40
|
-
end
|
data/lib/explicit/spec/record.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::Record
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(attributes)
|
7
|
-
attributes_validators = attributes.map do |attribute_name, attribute_spec|
|
8
|
-
[attribute_name, Explicit::Spec.build(attribute_spec)]
|
9
|
-
end
|
10
|
-
|
11
|
-
lambda do |data|
|
12
|
-
return [:error, :hash] if !data.respond_to?(:[])
|
13
|
-
|
14
|
-
validated_data = {}
|
15
|
-
errors = {}
|
16
|
-
|
17
|
-
attributes_validators.each do |attribute_name, attribute_validator|
|
18
|
-
value = data[attribute_name]
|
19
|
-
|
20
|
-
case attribute_validator.call(value)
|
21
|
-
in [:ok, validated_value]
|
22
|
-
validated_data[attribute_name] = validated_value
|
23
|
-
in [:error, err]
|
24
|
-
errors[attribute_name] = err
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
return [:error, errors] if errors.any?
|
29
|
-
|
30
|
-
[:ok, validated_data]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/lib/explicit/spec/string.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec::String
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(options)
|
7
|
-
lambda do |value|
|
8
|
-
return [:error, :string] if !value.is_a?(::String)
|
9
|
-
|
10
|
-
value = value.strip if options[:strip]
|
11
|
-
|
12
|
-
if options.key?(:empty) && !validate_empty(value, options[:empty])
|
13
|
-
return [:error, :empty]
|
14
|
-
end
|
15
|
-
|
16
|
-
if (minlength = options[:minlength]) && !validate_minlength(value, minlength)
|
17
|
-
return [:error, [:minlength, minlength:]]
|
18
|
-
end
|
19
|
-
|
20
|
-
if (maxlength = options[:maxlength]) && !validate_maxlength(value, maxlength)
|
21
|
-
return [:error, [:maxlength, maxlength:]]
|
22
|
-
end
|
23
|
-
|
24
|
-
if (format = options[:format]) && !validate_format(value, format)
|
25
|
-
return [:error, [:format, format]]
|
26
|
-
end
|
27
|
-
|
28
|
-
[:ok, value]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
def validate_empty(value, allow_empty)
|
34
|
-
return true if allow_empty
|
35
|
-
|
36
|
-
!value.empty?
|
37
|
-
end
|
38
|
-
|
39
|
-
def validate_minlength(value, minlength)
|
40
|
-
value.length >= minlength
|
41
|
-
end
|
42
|
-
|
43
|
-
def validate_maxlength(value, maxlength)
|
44
|
-
value.length <= maxlength
|
45
|
-
end
|
46
|
-
|
47
|
-
def validate_format(value, format)
|
48
|
-
format.match?(value)
|
49
|
-
end
|
50
|
-
end
|
data/lib/explicit/spec.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Explicit::Spec
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def build(spec)
|
7
|
-
case spec
|
8
|
-
in :agreement
|
9
|
-
Explicit::Spec::Agreement.build({})
|
10
|
-
in [:agreement, options]
|
11
|
-
Explicit::Spec::Agreement.build(options)
|
12
|
-
|
13
|
-
in [:array, itemspec]
|
14
|
-
Explicit::Spec::Array.build(itemspec, {})
|
15
|
-
in [:array, itemspec, options]
|
16
|
-
Explicit::Spec::Array.build(itemspec, options)
|
17
|
-
|
18
|
-
in :bigdecimal
|
19
|
-
Explicit::Spec::Bigdecimal.build({})
|
20
|
-
in [:bigdecimal, options]
|
21
|
-
Explicit::Spec::Bigdecimal.build(options)
|
22
|
-
|
23
|
-
in :boolean
|
24
|
-
Explicit::Spec::Boolean.build({})
|
25
|
-
in [:boolean, options]
|
26
|
-
Explicit::Spec::Boolean.build(options)
|
27
|
-
|
28
|
-
in :date_time_iso8601
|
29
|
-
Explicit::Spec::DateTimeISO8601
|
30
|
-
in :date_time_posix
|
31
|
-
Explicit::Spec::DateTimePosix
|
32
|
-
|
33
|
-
in [:default, defaultval, subspec]
|
34
|
-
Explicit::Spec::Default.build(defaultval, subspec)
|
35
|
-
|
36
|
-
in [:description, _, subspec]
|
37
|
-
Explicit::Spec.build(subspec)
|
38
|
-
|
39
|
-
in [:hash, keyspec, valuespec]
|
40
|
-
Explicit::Spec::Hash.build(keyspec, valuespec, {})
|
41
|
-
in [:hash, keyspec, valuespec, options]
|
42
|
-
Explicit::Spec::Hash.build(keyspec, valuespec, options)
|
43
|
-
|
44
|
-
in [:inclusion, options]
|
45
|
-
Explicit::Spec::Inclusion.build(options)
|
46
|
-
|
47
|
-
in :integer
|
48
|
-
Explicit::Spec::Integer.build({})
|
49
|
-
in [:integer, options]
|
50
|
-
Explicit::Spec::Integer.build(options)
|
51
|
-
|
52
|
-
in [:literal, value]
|
53
|
-
Explicit::Spec::Literal.build(value)
|
54
|
-
in ::String
|
55
|
-
Explicit::Spec::Literal.build(spec)
|
56
|
-
|
57
|
-
in [:nilable, options]
|
58
|
-
Explicit::Spec::Nilable.build(options)
|
59
|
-
|
60
|
-
in [:one_of, *subspecs]
|
61
|
-
Explicit::Spec::OneOf.build(subspecs)
|
62
|
-
|
63
|
-
in :string
|
64
|
-
Explicit::Spec::String.build({})
|
65
|
-
in [:string, options]
|
66
|
-
Explicit::Spec::String.build(options)
|
67
|
-
|
68
|
-
in ::Hash
|
69
|
-
Explicit::Spec::Record.build(spec)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|