meta-api 0.1.2 → 0.2.0
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/lib/meta/api.rb +1 -0
- data/lib/meta/json_schema/builders/object_schema_builder.rb +52 -50
- data/lib/meta/json_schema/builders/schema_builder_tool.rb +31 -20
- data/lib/meta/json_schema/schemas/base_schema.rb +2 -24
- data/lib/meta/json_schema/schemas/object_schema.rb +5 -38
- data/lib/meta/json_schema/schemas/properties.rb +4 -0
- data/lib/meta/json_schema/schemas/ref_schema.rb +0 -7
- data/lib/meta/json_schema/schemas/scoping_schema.rb +0 -1
- data/lib/meta/json_schema/schemas/staging_schema.rb +4 -1
- data/lib/meta/json_schema/support/schema_options.rb +87 -18
- data/lib/meta/route_dsl/parameters_builder.rb +3 -3
- data/lib/meta/route_dsl/route_builder.rb +0 -1
- data/lib/meta/route_dsl/uniformed_params_builder.rb +3 -3
- data/lib/meta/utils/kwargs/builder.rb +17 -74
- data/lib/meta/utils/kwargs/checker.rb +27 -26
- data/lib/meta/utils/kwargs/consumers.rb +64 -0
- data/lib/meta/utils/kwargs/extras_consumers.rb +33 -0
- data/lib/meta/utils/kwargs/helpers.rb +36 -0
- data/meta-api.gemspec +1 -1
- metadata +5 -3
- data/lib/meta/utils/kwargs/check.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 176e67a6d2a121ef7841ec614a2104f7f5f201c863ea88eb805e450b9ab13ee4
|
4
|
+
data.tar.gz: bd9be253deb822db45e2bf1c0548467652155dbf39255d49709da7b7d5a56726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d1e5c80f3699d00bd529b74da7881eb559c089ab0bbb088560599453eea2972dc38dd082d991fc0be5e2815509987e8a3176d4d3fb0b041d35ae4ec5682c665
|
7
|
+
data.tar.gz: 59fcbd0be04d0d94a768f5b63e46a5ffcbc3a0a67ed89959ff957f8be4d1f9b7d04551cc090f6cc3a031effe45cebcb369d4a10f31fbc7a5811e2760a7f0b335
|
data/lib/meta/api.rb
CHANGED
@@ -7,37 +7,38 @@ module Meta
|
|
7
7
|
class ObjectSchemaBuilder
|
8
8
|
extend Forwardable
|
9
9
|
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
class Locked
|
11
|
+
# 定义一些 locked 的别名方法
|
12
|
+
module LockedMethodAlias
|
13
|
+
# 我在这里说明一下 lock_scope 的逻辑。
|
14
|
+
# 1. lock_scope 实际上是将 scope 传递到当前的 ObjectSchema 和它的子 Schema 中。
|
15
|
+
# 2. lock_scope 会叠加,也就是如果子 schema 也有 lock_scope,那么子 Schema 会将两个 Schema 合并起来。
|
16
|
+
# 3. 调用 filter(scope:) 和 to_schema_doc(scope:) 时,可以传递 scope 参数,这个 scope 遇到 lock_scope 时会合并。
|
17
|
+
# 4. 这也就是说,在路由级别定义的 scope 宏会传递到下面的 Schema 中去。
|
18
|
+
def add_scope(scope)
|
19
|
+
lock_scope(scope)
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
def lock(key, value)
|
23
|
+
locked(key => value)
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def method_missing(method, *args)
|
27
|
+
if method =~ /^lock_(\w+)$/
|
28
|
+
key = Regexp.last_match(1)
|
29
|
+
lock(key.to_sym, *args)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
30
33
|
end
|
31
34
|
end
|
32
|
-
end
|
33
35
|
|
34
|
-
class Locked
|
35
36
|
attr_reader :object_schema_builder, :locked_options
|
36
37
|
|
37
38
|
# locked_options 是用户传递的参数,这个参数会被合并到 object_schema_builder 的 locked_options 中。
|
38
|
-
def initialize(builder,
|
39
|
+
def initialize(builder, **locked_options)
|
39
40
|
@object_schema_builder = builder
|
40
|
-
@locked_options =
|
41
|
+
@locked_options = SchemaOptions::UserOptions::Filter.check(locked_options.compact)
|
41
42
|
end
|
42
43
|
|
43
44
|
def to_schema
|
@@ -45,7 +46,7 @@ module Meta
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def locked(options)
|
48
|
-
options =
|
49
|
+
options = SchemaOptions::UserOptions::Filter.check(options)
|
49
50
|
options = ObjectSchema.merge_user_options(locked_options, options)
|
50
51
|
Locked.new(self.object_schema_builder, **options)
|
51
52
|
end
|
@@ -89,6 +90,8 @@ module Meta
|
|
89
90
|
def initialize(options = {}, &)
|
90
91
|
raise 'type 选项必须是 object' if !options[:type].nil? && options[:type] != 'object'
|
91
92
|
|
93
|
+
@schema_cache = {} # 用于缓存已经生成的 schema,重复利用
|
94
|
+
|
92
95
|
@properties = {} # 所有的属性已经生成
|
93
96
|
@required = []
|
94
97
|
@validations = {}
|
@@ -98,7 +101,13 @@ module Meta
|
|
98
101
|
@options = options
|
99
102
|
|
100
103
|
properties&.each do |name, property_options|
|
101
|
-
|
104
|
+
if property_options.is_a?(Hash)
|
105
|
+
property name, property_options
|
106
|
+
elsif property_options.is_a?(BaseSchema)
|
107
|
+
@properties[name.to_sym] = property_options
|
108
|
+
else
|
109
|
+
raise ArgumentError, "属性 #{name} 的类型不正确"
|
110
|
+
end
|
102
111
|
end
|
103
112
|
|
104
113
|
instance_exec(&) if block_given?
|
@@ -115,6 +124,7 @@ module Meta
|
|
115
124
|
|
116
125
|
def property(name, options = {}, &block)
|
117
126
|
@properties[name.to_sym] = Properties.build_property(options, ->(options) { SchemaBuilderTool.build(options, &block) })
|
127
|
+
# @properties[name.to_sym] = SchemaBuilderTool.build(options, &block)
|
118
128
|
end
|
119
129
|
|
120
130
|
alias expose property
|
@@ -139,7 +149,7 @@ module Meta
|
|
139
149
|
end
|
140
150
|
|
141
151
|
def render(options = {}, &block)
|
142
|
-
with_common_options(**options,
|
152
|
+
with_common_options(**options, param: false, &block)
|
143
153
|
end
|
144
154
|
|
145
155
|
def merge(schema_builder)
|
@@ -148,41 +158,33 @@ module Meta
|
|
148
158
|
@properties.merge!(schema_builder.properties)
|
149
159
|
end
|
150
160
|
|
151
|
-
def
|
161
|
+
def within(*properties)
|
162
|
+
to_schema.properties.within(*properties)
|
163
|
+
end
|
164
|
+
alias_method :[], :within
|
165
|
+
|
166
|
+
def to_schema(locked_options = {})
|
167
|
+
locked_options = SchemaOptions::UserOptions::Filter.check(locked_options.compact)
|
168
|
+
return @schema_cache[locked_options] if @schema_cache[locked_options]
|
169
|
+
|
152
170
|
properties = @schema_name ? NamedProperties.new(@properties, @schema_name) : Properties.new(@properties)
|
153
|
-
ObjectSchema.new(properties: properties, options: @options, locked_options: locked_options)
|
171
|
+
@schema_cache[locked_options] = ObjectSchema.new(properties: properties, options: @options, locked_options: locked_options)
|
154
172
|
end
|
155
173
|
|
156
174
|
def locked(options)
|
157
|
-
# defined_scopes_mapping = {}
|
158
|
-
# # TODO: 将 properties 搞成 Properties 可以吗?
|
159
|
-
# defined_scopes = properties.map do |key, property|
|
160
|
-
# property.defined_scopes(stage: :param, defined_scopes_mapping: defined_scopes_mapping)
|
161
|
-
# end.flatten.uniq
|
162
|
-
#
|
163
|
-
# user_scopes = options[:scope] || []
|
164
|
-
# user_scopes = [user_scopes] unless user_scopes.is_a?(Array)
|
165
|
-
#
|
166
|
-
# # 判断 user_scopes 中提供的局部 scope 是否在 defined_scopes 中
|
167
|
-
# local_user_scopes = user_scopes.reject { |scope| scope.start_with?('$') }
|
168
|
-
# if (local_user_scopes - defined_scopes).any?
|
169
|
-
# extra_scopes = local_user_scopes - defined_scopes
|
170
|
-
# raise ArgumentError, "scope #{extra_scopes.join(',')} 未在实体中定义"
|
171
|
-
# end
|
172
|
-
|
173
175
|
Locked.new(self, **options)
|
174
176
|
end
|
175
|
-
include LockedMethodAlias
|
177
|
+
include Locked::LockedMethodAlias
|
176
178
|
|
177
179
|
private
|
178
180
|
|
179
|
-
|
180
|
-
|
181
|
-
|
181
|
+
def apply_array_scope?(options, block)
|
182
|
+
options[:type] == 'array' && (options[:items] || block)
|
183
|
+
end
|
182
184
|
|
183
|
-
|
184
|
-
|
185
|
-
|
185
|
+
def apply_object_scope?(options, block)
|
186
|
+
(options[:type] == 'object' || block) && (options[:properties] || block)
|
187
|
+
end
|
186
188
|
end
|
187
189
|
end
|
188
190
|
end
|
@@ -10,16 +10,16 @@ module Meta
|
|
10
10
|
module JsonSchema
|
11
11
|
class SchemaBuilderTool
|
12
12
|
class << self
|
13
|
-
SCHEMA_BUILDER_OPTIONS = Utils::KeywordArgs::Builder.build do
|
14
|
-
permit_extras true
|
15
|
-
|
16
|
-
key :ref, alias_names: [:using], normalizer: ->(entity) { entity }
|
17
|
-
key :dynamic_ref, alias_names: [:dynamic_using], normalizer: ->(value) { value.is_a?(Proc) ? { resolve: value } : value }
|
18
|
-
end
|
19
13
|
def build(options = {}, &block)
|
20
|
-
options =
|
14
|
+
options = SchemaOptions::BaseBuildOptions.check(options)
|
15
|
+
SchemaOptions.fix_type_option!(options)
|
21
16
|
|
22
|
-
if
|
17
|
+
if apply_staging_schema?(options)
|
18
|
+
# 原则上,SchemaBuilderTool 不处理 param render scope 选项,这几个选项只会在 property 宏中出现,
|
19
|
+
# 并且交由 StagingSchema 和 ScopingSchema 专业处理。
|
20
|
+
# 只不过,经过后置修复后可能包含了 param 和 render 选项
|
21
|
+
StagingSchema.build_from_options(options)
|
22
|
+
elsif apply_array_schema?(options, block)
|
23
23
|
ArraySchemaBuilder.new(options, &block).to_schema
|
24
24
|
elsif apply_ref_schema?(options, block)
|
25
25
|
RefSchemaBuilder.new(options).to_schema
|
@@ -34,21 +34,32 @@ module Meta
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def apply_staging_schema?(options)
|
38
|
+
if options.key?(:param)
|
39
|
+
return true if options[:param] == false || !options[:param].empty?
|
40
|
+
end
|
41
|
+
if options.key?(:render)
|
42
|
+
return true if options[:render] == false || !options[:render].empty?
|
43
|
+
end
|
44
|
+
false
|
45
|
+
end
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
47
|
+
def apply_array_schema?(options, block)
|
48
|
+
options[:type] == 'array'
|
49
|
+
end
|
44
50
|
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
def apply_object_schema?(options, block)
|
52
|
+
options[:properties] || block
|
53
|
+
end
|
54
|
+
|
55
|
+
def apply_ref_schema?(options, block)
|
56
|
+
options[:ref] != nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def apply_dynamic_schema?(options, block)
|
60
|
+
options[:dynamic_ref] != nil
|
61
|
+
end
|
48
62
|
|
49
|
-
def apply_dynamic_schema?(options, block)
|
50
|
-
options[:dynamic_ref] != nil
|
51
|
-
end
|
52
63
|
end
|
53
64
|
end
|
54
65
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../utils/kwargs/check'
|
4
3
|
require_relative '../support/schema_options'
|
5
4
|
|
6
5
|
module Meta
|
@@ -20,24 +19,6 @@ module Meta
|
|
20
19
|
# 的地方都会抛出异常(NoMethodError: undefined method `[]' for nil:NilClass)。这种模式
|
21
20
|
# 的案例很多,包括 StagingSchema、RefSchema 等。
|
22
21
|
class BaseSchema
|
23
|
-
OPTIONS_CHECKER = Utils::KeywordArgs::Builder.build do
|
24
|
-
key :type, :items, :description, :presenter, :value, :default, :properties, :convert
|
25
|
-
key :validate, :required, :format
|
26
|
-
key :enum, alias_names: [:allowable]
|
27
|
-
key :dynamic_ref, alias_names: [:dynamic_using], normalizer: ->(value) { value.is_a?(Proc) ? { resolve: value } : value }
|
28
|
-
key :before, :after
|
29
|
-
key :if
|
30
|
-
end
|
31
|
-
|
32
|
-
USER_OPTIONS_CHECKER = Utils::KeywordArgs::Builder.build do
|
33
|
-
key :execution, :object_value, :type_conversion, :validation, :user_data
|
34
|
-
key :stage, validator: ->(value) { raise ArgumentError, "stage 只能取值为 :param 或 :render" unless [:param, :render].include?(value) }
|
35
|
-
|
36
|
-
# 以下是 ObjectSchema 需要的选项
|
37
|
-
# extra_properties 只能取值为 :ignore、:raise_error
|
38
|
-
key :discard_missing, :extra_properties, :exclude, :scope
|
39
|
-
end
|
40
|
-
|
41
22
|
# `options` 包含了转换器、验证器、文档、选项。
|
42
23
|
#
|
43
24
|
# 由于本对象可继承,基于不同的继承可分别表示基本类型、对象和数组,所以该属
|
@@ -49,10 +30,7 @@ module Meta
|
|
49
30
|
|
50
31
|
def initialize(options = {})
|
51
32
|
raise ArgumentError, 'options 必须是 Hash 类型' unless options.is_a?(Hash)
|
52
|
-
options =
|
53
|
-
raise '不允许 BaseSchema 直接接受 array 类型,必须通过继承使用 ArraySchema' if options[:type] == 'array' && self.class == BaseSchema
|
54
|
-
|
55
|
-
@options = SchemaOptions.normalize(options).freeze
|
33
|
+
@options = SchemaOptions::BaseBuildOptions.check(options)
|
56
34
|
end
|
57
35
|
|
58
36
|
def filter?
|
@@ -60,7 +38,7 @@ module Meta
|
|
60
38
|
end
|
61
39
|
|
62
40
|
def filter(value, user_options = {})
|
63
|
-
user_options =
|
41
|
+
user_options = SchemaOptions::UserOptions::Filter.check(user_options)
|
64
42
|
|
65
43
|
value = value_callback(user_options) if options[:value]
|
66
44
|
value = before_callback(value, user_options) if options[:before]
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../utils/kwargs/check'
|
4
3
|
require_relative 'named_properties'
|
5
4
|
|
6
5
|
module Meta
|
@@ -11,39 +10,6 @@ module Meta
|
|
11
10
|
# scope:、discard_missing:、exclude: 等
|
12
11
|
attr_reader :locked_options
|
13
12
|
|
14
|
-
normalize_scope = ->(value) {
|
15
|
-
raise ArgumentError, 'scope 选项不可传递 nil' if value.nil?
|
16
|
-
value = [value] unless value.is_a?(Array)
|
17
|
-
value.map do |v|
|
18
|
-
# 只要加入了 Meta::Scope::Base 模块,就有与 Meta::Scope 一样的行为
|
19
|
-
next v if v.is_a?(Meta::Scope::Base)
|
20
|
-
|
21
|
-
# 将 v 类名化
|
22
|
-
scope_name = v.to_s.split('_').map(&:capitalize).join
|
23
|
-
# 如果符号对应的类名不存在,就报错
|
24
|
-
if !defined?(::Scopes) || !::Scopes.const_defined?(scope_name)
|
25
|
-
raise NameError, "未找到常量 Scopes::#{scope_name}。如果你用的是命名 Scope(字符串或符号),则检查一下是不是拼写错误"
|
26
|
-
end
|
27
|
-
# 返回对应的常量
|
28
|
-
::Scopes.const_get(scope_name)
|
29
|
-
end.compact
|
30
|
-
}
|
31
|
-
# stage 和 scope 选项在两个 CHECKER 下都用到了
|
32
|
-
USER_OPTIONS_CHECKER = Utils::KeywordArgs::Builder.build do
|
33
|
-
key :stage
|
34
|
-
key :scope, normalizer: normalize_scope
|
35
|
-
key :discard_missing, :exclude, :extra_properties, :type_conversion, :validation
|
36
|
-
key :execution, :user_data, :object_value
|
37
|
-
end
|
38
|
-
TO_SCHEMA_DOC_CHECKER = Utils::KeywordArgs::Builder.build do
|
39
|
-
key :stage
|
40
|
-
key :scope, normalizer: normalize_scope
|
41
|
-
key :schema_docs_mapping, :defined_scopes_mapping
|
42
|
-
|
43
|
-
# 以下是 filter 用到的选项,讲道理这些选项应该是不需要的,放置这些是为了防止报错
|
44
|
-
key :discard_missing
|
45
|
-
end
|
46
|
-
|
47
13
|
def initialize(properties:, options: {}, locked_options: {})
|
48
14
|
raise ArgumentError, 'properties 必须是 Properties 实例' unless properties.is_a?(Properties)
|
49
15
|
|
@@ -51,19 +17,20 @@ module Meta
|
|
51
17
|
|
52
18
|
@properties = properties || Properties.new({}) # property 包含 stage,stage 包含 scope、schema
|
53
19
|
@properties = Properties.new(@properties) if @properties.is_a?(Hash)
|
54
|
-
@locked_options =
|
20
|
+
@locked_options = SchemaOptions::UserOptions::Filter.check(locked_options || {}, extras_handler: :ignore)
|
21
|
+
@locked_to_doc_options = SchemaOptions::UserOptions::ToDoc.check(locked_options || {}, extras_handler: :ignore)
|
55
22
|
end
|
56
23
|
|
57
24
|
def filter(object_value, user_options = {})
|
58
25
|
# 合并 user_options
|
59
|
-
user_options =
|
26
|
+
user_options = SchemaOptions::UserOptions::Filter.check(user_options)
|
60
27
|
user_options = self.class.merge_user_options(user_options, locked_options) if locked_options
|
61
28
|
super
|
62
29
|
end
|
63
30
|
|
64
31
|
def to_schema_doc(user_options = {})
|
65
|
-
user_options =
|
66
|
-
user_options = self.class.merge_user_options(user_options,
|
32
|
+
user_options = SchemaOptions::UserOptions::ToDoc.check(user_options)
|
33
|
+
user_options = self.class.merge_user_options(user_options, @locked_to_doc_options) if @locked_to_doc_options
|
67
34
|
|
68
35
|
schema = { type: 'object' }
|
69
36
|
schema[:description] = options[:description] if options[:description]
|
@@ -94,6 +94,10 @@ module Meta
|
|
94
94
|
self.class.new(@properties.merge(properties.instance_eval { @properties }))
|
95
95
|
end
|
96
96
|
|
97
|
+
def within(*properties)
|
98
|
+
self.class.new(@properties.slice(*properties))
|
99
|
+
end
|
100
|
+
|
97
101
|
def self.build_property(*args)
|
98
102
|
StagingSchema.build_from_options(*args)
|
99
103
|
end
|
@@ -54,13 +54,6 @@ module Meta
|
|
54
54
|
defined_scopes_mapping[schema_name] = defined_scopes
|
55
55
|
defined_scopes
|
56
56
|
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
# # TODO: 这种带有组合方式的 Schema,让我联想到,每次 BaseSchema 新增一个方法都要在子 Schema 中加一遍,很烦!
|
61
|
-
# def defined_scopes
|
62
|
-
# schema.defined_scopes
|
63
|
-
# end
|
64
57
|
end
|
65
58
|
end
|
66
59
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../utils/kwargs/check'
|
4
3
|
require_relative '../support/schema_options'
|
5
4
|
require_relative 'scoping_schema'
|
6
5
|
require_relative 'unsupported_schema'
|
@@ -43,6 +42,10 @@ module Meta
|
|
43
42
|
staged(stage).defined_scopes(stage: stage, **kwargs)
|
44
43
|
end
|
45
44
|
|
45
|
+
def to_schema_doc(stage:, **kwargs)
|
46
|
+
staged(stage).to_schema_doc(stage: stage, **kwargs)
|
47
|
+
end
|
48
|
+
|
46
49
|
def self.build_from_options(options, build_schema = ->(opts) { BaseSchema.new(opts) })
|
47
50
|
param_opts, render_opts, common_opts = SchemaOptions.divide_to_param_and_render(options)
|
48
51
|
if param_opts == common_opts && render_opts == common_opts
|
@@ -5,12 +5,64 @@ require_relative '../../utils/kwargs/builder'
|
|
5
5
|
module Meta
|
6
6
|
module JsonSchema
|
7
7
|
module SchemaOptions
|
8
|
-
|
9
|
-
|
10
|
-
required:
|
11
|
-
|
8
|
+
BaseBuildOptions = Utils::Kwargs::Builder.build do
|
9
|
+
key :type, :items, :description, :presenter, :value, :default, :properties, :convert
|
10
|
+
key :validate, :required, :format
|
11
|
+
key :enum, alias_names: [:allowable]
|
12
|
+
key :ref, alias_names: [:using], normalizer: ->(entity) { entity }
|
13
|
+
key :dynamic_ref, alias_names: [:dynamic_using], normalizer: ->(value) { value.is_a?(Proc) ? { resolve: value } : value }
|
14
|
+
key :before, :after
|
15
|
+
key :if
|
16
|
+
end
|
17
|
+
|
18
|
+
module UserOptions
|
19
|
+
Common = Utils::Kwargs::Builder.build do
|
20
|
+
key :stage
|
21
|
+
key :scope, normalizer: ->(value) {
|
22
|
+
raise ArgumentError, 'scope 选项不可传递 nil' if value.nil?
|
23
|
+
value = [value] unless value.is_a?(Array)
|
24
|
+
value.map do |v|
|
25
|
+
# 只要加入了 Meta::Scope::Base 模块,就有与 Meta::Scope 一样的行为
|
26
|
+
next v if v.is_a?(Meta::Scope::Base)
|
27
|
+
|
28
|
+
# 将 v 类名化
|
29
|
+
scope_name = v.to_s.split('_').map(&:capitalize).join
|
30
|
+
# 如果符号对应的类名不存在,就报错
|
31
|
+
if !defined?(::Scopes) || !::Scopes.const_defined?(scope_name)
|
32
|
+
raise NameError, "未找到常量 Scopes::#{scope_name}。如果你用的是命名 Scope(字符串或符号),则检查一下是不是拼写错误"
|
33
|
+
end
|
34
|
+
# 返回对应的常量
|
35
|
+
::Scopes.const_get(scope_name)
|
36
|
+
end.compact
|
37
|
+
}
|
38
|
+
|
39
|
+
handle_extras :merged
|
40
|
+
end
|
41
|
+
ToDoc = Utils::Kwargs::Builder.build(Common) do
|
42
|
+
key :schema_docs_mapping, :defined_scopes_mapping
|
43
|
+
end
|
44
|
+
Filter = Utils::Kwargs::Builder.build(Common) do
|
45
|
+
key :discard_missing, :exclude, :extra_properties, :type_conversion, :validation
|
46
|
+
key :execution, :user_data, :object_value
|
47
|
+
end
|
48
|
+
end
|
12
49
|
|
13
50
|
class << self
|
51
|
+
def fix_type_option!(options)
|
52
|
+
if options[:type].is_a?(Class)
|
53
|
+
# 修复 type 为自定义类的情形
|
54
|
+
the_class = options[:type]
|
55
|
+
# 修复 param 选项
|
56
|
+
options[:param] = {} if options[:param].nil?
|
57
|
+
make_after_cast_to_class(options[:param], the_class) if options[:param]
|
58
|
+
# 修复 render 选项
|
59
|
+
options[:render] = {} if options[:render].nil?
|
60
|
+
make_before_match_to_class(options[:render], the_class) if options[:render]
|
61
|
+
# 最终确保 type 为 object
|
62
|
+
options.merge!(type: 'object')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
14
66
|
def divide_to_param_and_render(options)
|
15
67
|
common_opts = (options || {}).dup
|
16
68
|
param_opts = common_opts.delete(:param)
|
@@ -21,20 +73,6 @@ module Meta
|
|
21
73
|
[param_opts, render_opts, common_opts]
|
22
74
|
end
|
23
75
|
|
24
|
-
def normalize(options)
|
25
|
-
# 只要 options 中设置为 nil 的选项没有明确的意义,则下行代码是永远有效的
|
26
|
-
options = (@default_options.compact).merge(options.compact)
|
27
|
-
if options[:using]
|
28
|
-
if options[:type].nil?
|
29
|
-
options[:type] = 'object'
|
30
|
-
elsif options[:type] != 'object' && options[:type] != 'array'
|
31
|
-
raise "当使用 using 时,type 必须声明为 object 或 array"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
options
|
36
|
-
end
|
37
|
-
|
38
76
|
private
|
39
77
|
|
40
78
|
def merge_common_to_stage(common_opts, stage_opts)
|
@@ -42,6 +80,37 @@ module Meta
|
|
42
80
|
stage_opts = common_opts.merge(stage_opts) if stage_opts
|
43
81
|
stage_opts
|
44
82
|
end
|
83
|
+
|
84
|
+
def make_after_cast_to_class(options, the_class)
|
85
|
+
if options[:after].nil?
|
86
|
+
options[:after] = ->(value) { the_class.new(value) }
|
87
|
+
else
|
88
|
+
# 如果用户自定义了 after,那么我们需要在 after 之后再包一层
|
89
|
+
original_after_block = options[:after]
|
90
|
+
options[:after] = ->(value) do
|
91
|
+
value = instance_exec(value, &original_after_block)
|
92
|
+
the_class.new(value)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def make_before_match_to_class(options, the_class)
|
98
|
+
match_class = ->(value) do
|
99
|
+
raise ValidationError, "value 必须是 #{the_class} 类型" unless value.is_a?(the_class)
|
100
|
+
value
|
101
|
+
end
|
102
|
+
if options[:before].nil?
|
103
|
+
options[:before] = match_class
|
104
|
+
else
|
105
|
+
# 如果用户自定义了 before,那么我们需要在 before 之前再包一层
|
106
|
+
original_before_block = options[:before]
|
107
|
+
options[:before] = ->(value) do
|
108
|
+
value = match_class.call(value)
|
109
|
+
instance_exec(value, &original_before_block)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
45
114
|
end
|
46
115
|
end
|
47
116
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../application/parameters'
|
4
|
-
require_relative '../utils/kwargs/
|
4
|
+
require_relative '../utils/kwargs/helpers'
|
5
5
|
|
6
6
|
module Meta
|
7
7
|
module RouteDSL
|
@@ -18,9 +18,9 @@ module Meta
|
|
18
18
|
# 修正 path 参数的选项
|
19
19
|
options = options.dup
|
20
20
|
if path_param_names.include?(name) # path 参数
|
21
|
-
options = Utils::
|
21
|
+
options = Utils::Kwargs::Helpers.fix!(options, in: 'path', required: true)
|
22
22
|
else
|
23
|
-
options = Utils::
|
23
|
+
options = Utils::Kwargs::Helpers.merge_defaults!(options, in: 'query')
|
24
24
|
end
|
25
25
|
|
26
26
|
in_op = options.delete(:in)
|
@@ -16,11 +16,11 @@ module Meta
|
|
16
16
|
def param(name, options = {}, &block)
|
17
17
|
options = (options || {}).dup
|
18
18
|
if path_param_names.include?(name)
|
19
|
-
options = Utils::
|
19
|
+
options = Utils::Kwargs::Helpers.fix!(options, in: 'path', required: true)
|
20
20
|
elsif @route_method == :get
|
21
|
-
options = Utils::
|
21
|
+
options = Utils::Kwargs::Helpers.merge_defaults!(options, in: 'query')
|
22
22
|
else
|
23
|
-
options = Utils::
|
23
|
+
options = Utils::Kwargs::Helpers.merge_defaults!(options, in: 'body')
|
24
24
|
end
|
25
25
|
|
26
26
|
if options[:in] == 'body'
|
@@ -17,101 +17,44 @@
|
|
17
17
|
# key :a, :b, :c
|
18
18
|
# key :d, normalizer: ->(value) { normalize_to_array(value) }
|
19
19
|
# end
|
20
|
-
|
20
|
+
|
21
|
+
require_relative 'consumers'
|
22
|
+
require_relative 'extras_consumers'
|
23
|
+
require_relative 'checker'
|
21
24
|
|
22
25
|
module Meta
|
23
26
|
module Utils
|
24
|
-
class
|
25
|
-
def initialize(arguments, permit_extras = false, final_consumer = nil)
|
26
|
-
@arguments = arguments
|
27
|
-
@permit_extras = permit_extras
|
28
|
-
@final_consumer = final_consumer
|
29
|
-
end
|
30
|
-
|
31
|
-
def check(args)
|
32
|
-
args = args.dup
|
33
|
-
final_args = {}
|
34
|
-
|
35
|
-
@arguments.each do |argument|
|
36
|
-
argument.consume(final_args, args)
|
37
|
-
end
|
38
|
-
|
39
|
-
# 做最终的修饰
|
40
|
-
@final_consumer.call(final_args, args) if @final_consumer
|
41
|
-
|
42
|
-
# 处理剩余字段
|
43
|
-
unless args.keys.empty?
|
44
|
-
if @permit_extras
|
45
|
-
final_args.merge!(args)
|
46
|
-
else
|
47
|
-
extras = args.keys
|
48
|
-
raise ArgumentError, "不接受额外的关键字参数:#{extras.join(', ')}" unless extras.empty?
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
final_args
|
53
|
-
end
|
54
|
-
|
55
|
-
class Argument
|
56
|
-
DEFAULT_TRANSFORMER = ->(value) { value }
|
57
|
-
|
58
|
-
def initialize(name:, normalizer: DEFAULT_TRANSFORMER, validator: nil, default: nil, alias_names: [])
|
59
|
-
@key_name = name
|
60
|
-
@consumer_names = [name] + alias_names
|
61
|
-
@default_value = default
|
62
|
-
@normalizer = normalizer
|
63
|
-
@validator = validator
|
64
|
-
end
|
65
|
-
|
66
|
-
def consume(final_args, args)
|
67
|
-
@consumer_names.each do |name|
|
68
|
-
return if consume_name(final_args, args, name)
|
69
|
-
end
|
70
|
-
|
71
|
-
final_args[@key_name] = @default_value unless @default_value.nil?
|
72
|
-
end
|
73
|
-
|
74
|
-
def consume_name(final_args, args, consumer_name)
|
75
|
-
if args.key?(consumer_name)
|
76
|
-
value = @normalizer.call(args.delete(consumer_name))
|
77
|
-
@validator.call(value) if @validator
|
78
|
-
final_args[@key_name] = value
|
79
|
-
true
|
80
|
-
else
|
81
|
-
false
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
27
|
+
class Kwargs
|
86
28
|
class Builder
|
87
29
|
def initialize
|
88
30
|
@arguments = []
|
89
|
-
@
|
90
|
-
@final_consumer = nil
|
31
|
+
@handle_extras = ExtrasConsumers::RaiseError
|
91
32
|
end
|
92
33
|
|
93
34
|
def key(*names, **options)
|
94
35
|
names.each do |name|
|
95
|
-
@arguments <<
|
36
|
+
@arguments << ArgumentConsumer.new(name: name, **options)
|
96
37
|
end
|
97
38
|
end
|
98
39
|
|
99
|
-
def
|
100
|
-
@
|
40
|
+
def handle_extras(sym)
|
41
|
+
@handle_extras = ExtrasConsumers.resolve_handle_extras(sym)
|
101
42
|
end
|
102
43
|
|
103
|
-
def
|
104
|
-
@
|
44
|
+
def after_handler(&blk)
|
45
|
+
@after_handler = blk
|
105
46
|
end
|
106
47
|
|
107
|
-
def build
|
108
|
-
|
48
|
+
def build(base_consumer = nil)
|
49
|
+
consumers = [base_consumer, *@arguments].compact
|
50
|
+
consumers = CompositeConsumer.new(*consumers)
|
51
|
+
Checker.new(arguments_consumer: consumers, extras_consumer: @handle_extras, after_handler: @after_handler)
|
109
52
|
end
|
110
53
|
|
111
|
-
def self.build(&block)
|
54
|
+
def self.build(base_checker = nil, &block)
|
112
55
|
builder = Builder.new
|
113
56
|
builder.instance_exec &block
|
114
|
-
builder.build
|
57
|
+
builder.build(base_checker&.arguments_consumer)
|
115
58
|
end
|
116
59
|
end
|
117
60
|
end
|
@@ -2,33 +2,34 @@
|
|
2
2
|
|
3
3
|
module Meta
|
4
4
|
module Utils
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
# 将 options 内的值修正为固定值,该方法会原地修改 options 选项。
|
9
|
-
# 如果 options 中的缺失相应的值,则使用 fixed_values 中的值补充;如果 options 中的值不等于 fixed_values 中对应的值,则抛出异常。
|
10
|
-
# 示例:
|
11
|
-
# (1)fix!({}, { a: 1, b: 2 }) # => { a: 1, b: 2 }
|
12
|
-
# (2)fix!({ a: 1 }, { a: 2 }) # raise error
|
13
|
-
def fix!(options, fixed_values)
|
14
|
-
fixed_values.each do |key, value|
|
15
|
-
if options.include?(key)
|
16
|
-
if options[key] != value
|
17
|
-
raise ArgumentError, "关键字参数 #{key} 的值不正确,必须为 #{value}"
|
18
|
-
end
|
19
|
-
else
|
20
|
-
options[key] = value
|
21
|
-
end
|
22
|
-
end
|
23
|
-
options
|
24
|
-
end
|
5
|
+
class Kwargs
|
6
|
+
class Checker
|
7
|
+
attr_reader :arguments_consumer
|
25
8
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
9
|
+
def initialize(arguments_consumer:, extras_consumer: nil, after_handler: nil)
|
10
|
+
@arguments_consumer = arguments_consumer
|
11
|
+
@extras_consumer = extras_consumer || ExtrasConsumers::RaiseError
|
12
|
+
@after_handler = after_handler
|
13
|
+
end
|
14
|
+
|
15
|
+
def check(args, extras_handler: nil)
|
16
|
+
# 准备工作
|
17
|
+
args = args.dup
|
18
|
+
final_args = {}
|
19
|
+
|
20
|
+
# 逐个消费参数
|
21
|
+
@arguments_consumer.consume(final_args, args)
|
22
|
+
|
23
|
+
# 处理额外参数
|
24
|
+
extras_consumer = ExtrasConsumers.resolve_handle_extras(extras_handler)
|
25
|
+
extras_consumer ||= @extras_consumer
|
26
|
+
extras_consumer&.consume(final_args, args)
|
27
|
+
|
28
|
+
# 后置处理器
|
29
|
+
@after_handler&.call(final_args)
|
30
|
+
|
31
|
+
# 返回最终参数
|
32
|
+
final_args
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Meta
|
4
|
+
module Utils
|
5
|
+
class Kwargs
|
6
|
+
class ArgumentConsumer
|
7
|
+
DEFAULT_TRANSFORMER = ->(value) { value }
|
8
|
+
|
9
|
+
def initialize(name:, normalizer: DEFAULT_TRANSFORMER, validator: nil, default: nil, alias_names: [])
|
10
|
+
@key_name = name
|
11
|
+
@consumer_names = [name] + alias_names
|
12
|
+
@default_proc = -> { default.dup } if default
|
13
|
+
@normalizer = normalizer
|
14
|
+
@validator = validator
|
15
|
+
end
|
16
|
+
|
17
|
+
def consume(final_args, args)
|
18
|
+
@consumer_names.each do |name|
|
19
|
+
return if consume_name(final_args, args, name)
|
20
|
+
end
|
21
|
+
|
22
|
+
if @default_proc
|
23
|
+
default_value = @default_proc.call
|
24
|
+
final_args[@key_name] = @normalizer.call(default_value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def consume_name(final_args, args, consumer_name)
|
29
|
+
if args.key?(consumer_name)
|
30
|
+
value = @normalizer.call(args.delete(consumer_name))
|
31
|
+
@validator.call(value) if @validator
|
32
|
+
final_args[@key_name] = value
|
33
|
+
true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ProcConsumer
|
41
|
+
def initialize(&blk)
|
42
|
+
@block = blk
|
43
|
+
end
|
44
|
+
|
45
|
+
def consume(final_args, args)
|
46
|
+
@block.call(final_args, args) if @block
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class CompositeConsumer
|
51
|
+
def initialize(*consumers)
|
52
|
+
@consumers = consumers
|
53
|
+
end
|
54
|
+
|
55
|
+
def consume(final_args, args)
|
56
|
+
@consumers.each do |consumer|
|
57
|
+
consumer.consume(final_args, args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Meta
|
4
|
+
module Utils
|
5
|
+
class Kwargs
|
6
|
+
module ExtrasConsumers
|
7
|
+
Ignore = ProcConsumer.new
|
8
|
+
Merged = ProcConsumer.new do |final_args, args|
|
9
|
+
final_args.merge!(args)
|
10
|
+
end
|
11
|
+
RaiseError = ProcConsumer.new do |final_args, args|
|
12
|
+
extras_keys = args.keys
|
13
|
+
raise ArgumentError, "不接受额外的关键字参数:#{extras_keys.join(', ')}" unless extras_keys.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.resolve_handle_extras(sym)
|
17
|
+
return nil if sym.nil?
|
18
|
+
|
19
|
+
case sym
|
20
|
+
when :ignore
|
21
|
+
ExtrasConsumers::Ignore
|
22
|
+
when :merged
|
23
|
+
ExtrasConsumers::Merged
|
24
|
+
when :raise_error
|
25
|
+
ExtrasConsumers::RaiseError
|
26
|
+
else
|
27
|
+
raise ArgumentError, "handle_extras 只接受 :ignore, :merged, :raise_error 三种值,当前传递:#{sym}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Meta
|
4
|
+
module Utils
|
5
|
+
class Kwargs
|
6
|
+
module Helpers
|
7
|
+
class << self
|
8
|
+
# 将 options 内的值修正为固定值,该方法会原地修改 options 选项。
|
9
|
+
# 如果 options 中的缺失相应的值,则使用 fixed_values 中的值补充;如果 options 中的值不等于 fixed_values 中对应的值,则抛出异常。
|
10
|
+
# 示例:
|
11
|
+
# (1)fix!({}, { a: 1, b: 2 }) # => { a: 1, b: 2 }
|
12
|
+
# (2)fix!({ a: 1 }, { a: 2 }) # raise error
|
13
|
+
def fix!(options, fixed_values)
|
14
|
+
fixed_values.each do |key, value|
|
15
|
+
if options.include?(key)
|
16
|
+
if options[key] != value
|
17
|
+
raise ArgumentError, "关键字参数 #{key} 的值不正确,必须为 #{value}"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
options[key] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
options
|
24
|
+
end
|
25
|
+
|
26
|
+
def merge_defaults!(options, defaults)
|
27
|
+
defaults.each do |key, value|
|
28
|
+
options[key] = value unless options[key]
|
29
|
+
end
|
30
|
+
options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/meta-api.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meta-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yetrun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hash_to_struct
|
@@ -85,8 +85,10 @@ files:
|
|
85
85
|
- lib//meta/scope/utils.rb
|
86
86
|
- lib//meta/swagger_doc.rb
|
87
87
|
- lib//meta/utils/kwargs/builder.rb
|
88
|
-
- lib//meta/utils/kwargs/check.rb
|
89
88
|
- lib//meta/utils/kwargs/checker.rb
|
89
|
+
- lib//meta/utils/kwargs/consumers.rb
|
90
|
+
- lib//meta/utils/kwargs/extras_consumers.rb
|
91
|
+
- lib//meta/utils/kwargs/helpers.rb
|
90
92
|
- lib//meta/utils/path.rb
|
91
93
|
- lib//meta/utils/route_dsl_builders.rb
|
92
94
|
- meta-api.gemspec
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# 运行时检查关键字参数。(已过时,请使用 Builder)
|
4
|
-
#
|
5
|
-
# 在 Ruby 3 中,关键字参数有所变化。简单来说,关键字参数和 Hash 类型不再自动转化,并且一般情况下推荐使用关键字参数。
|
6
|
-
# 但关键字参数还是有稍稍不足之处,比如在做一些复杂的关键字参数定义时。
|
7
|
-
#
|
8
|
-
# 这个文件编写了一个方法,帮助我们在运行时检查关键字参数。这样,我们就可以像下面这样笼统的方式定义参数,不必用明确的关
|
9
|
-
# 键字参数名称。
|
10
|
-
#
|
11
|
-
# def method_name(x, y, z, **kwargs); end
|
12
|
-
# def method_name(x, y, z, kwargs={}); end
|
13
|
-
#
|
14
|
-
# 使用示例:
|
15
|
-
#
|
16
|
-
# # 返回 { x: 1, y: 2, z: 3 }
|
17
|
-
# Meta::Utils::KeywordArgs.check(args: { x: 1, y: 2 }, schema: [:x, :y, { z: 3 }])
|
18
|
-
#
|
19
|
-
# # 返回 { x: 1, y: 2, z: 4 }
|
20
|
-
# Meta::Utils::KeywordArgs.check(args: { x: 1, y: 2, z: 4 }, schema: [:x, :y, { z: 3 }])
|
21
|
-
#
|
22
|
-
# # Error: `x` is required
|
23
|
-
# Meta::Utils::KeywordArgs.check(args: { y: 2, z: 3 }, schema: [:x, :y, { z: 3 }])
|
24
|
-
#
|
25
|
-
# # Error: `a` is not allowed
|
26
|
-
# Meta::Utils::KeywordArgs.check(args: { a: 1, y: 2, z: 3 }, schema: [:x, :y, { z: 3 }])
|
27
|
-
|
28
|
-
module Meta
|
29
|
-
module Utils
|
30
|
-
class KeywordArgs
|
31
|
-
class << self
|
32
|
-
def check(args:, schema:)
|
33
|
-
schemas = build_schemas(schema)
|
34
|
-
|
35
|
-
# 不接受额外的关键字参数
|
36
|
-
extras = args.keys - schemas.keys
|
37
|
-
raise "不接受额外的关键字参数:#{extras.join(', ')}" unless extras.empty?
|
38
|
-
|
39
|
-
# 通过 schema 导出关键字参数
|
40
|
-
missing = []
|
41
|
-
result = schemas.map do |name, spec|
|
42
|
-
if args.include?(name)
|
43
|
-
[name, args[name]]
|
44
|
-
elsif spec.include?(:default)
|
45
|
-
[name, spec[:default]]
|
46
|
-
else
|
47
|
-
missing << name
|
48
|
-
end
|
49
|
-
end.to_h
|
50
|
-
|
51
|
-
# 检查以上导出过程中是否找到缺失的参数
|
52
|
-
if missing.empty?
|
53
|
-
result
|
54
|
-
else
|
55
|
-
raise "缺失必要的关键字参数:#{missing.join(', ')}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def build_schemas(spec)
|
62
|
-
if spec.is_a?(Array)
|
63
|
-
build_schemas_from_array(spec)
|
64
|
-
elsif spec.is_a?(Hash)
|
65
|
-
build_schemas_from_hash(spec)
|
66
|
-
elsif spec.is_a?(Symbol)
|
67
|
-
build_schemas_from_symbol(spec)
|
68
|
-
else
|
69
|
-
raise "未知的参数类型:#{spec.class}"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def build_schemas_from_array(spec_array)
|
74
|
-
spec_array.inject({}) do |accumulated, val|
|
75
|
-
accumulated.merge!(build_schemas(val))
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def build_schemas_from_hash(spec_hash)
|
80
|
-
spec_hash.transform_values do |val|
|
81
|
-
{ default: val }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def build_schemas_from_symbol(spec_symbol)
|
86
|
-
{ spec_symbol => {} }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|