Class: Meta::JsonSchema::Properties

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/meta/json_schema/schemas/properties.rb

Direct Known Subclasses

NamedProperties

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(properties) ⇒ Properties

Returns a new instance of Properties.



10
11
12
# File 'lib/meta/json_schema/schemas/properties.rb', line 10

def initialize(properties)
  @properties = properties
end

Class Method Details

.build_property(*args) ⇒ Object



101
102
103
# File 'lib/meta/json_schema/schemas/properties.rb', line 101

def self.build_property(*args)
  StagingSchema.build_from_options(*args)
end

Instance Method Details

#defined_scopes(stage:, defined_scopes_mapping:) ⇒ Object



84
85
86
87
88
# File 'lib/meta/json_schema/schemas/properties.rb', line 84

def defined_scopes(stage:, defined_scopes_mapping:)
  @properties.each_with_object([]) do |(name, property), defined_scopes|
    defined_scopes.concat(property.defined_scopes(stage: stage, defined_scopes_mapping: defined_scopes_mapping))
  end
end

#filter(object_value, user_options = {}) ⇒ Object

user_options 包括 stage, scope, extra_properties, discard_missing, exclude、execution、user_data



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/meta/json_schema/schemas/properties.rb', line 15

def filter(object_value, user_options = {})
  # 首先,要将 object_value 转化为 ObjectWrapper
  object_value = JsonObject.wrap(object_value)

  # 第一步,根据 user_options[:scope] 需要过滤一些字段
  stage = user_options[:stage]
  # 传递一个数字;因为 scope 不能包含数字,这里传递一个数字,使得凡是配置 scope 的属性都会被过滤
  user_scope = user_options[:scope] || [0]
  exclude = user_options.delete(:exclude) # 这里删除 exclude 选项,不要传递给下一层
  properties = filter_by(stage: stage, user_scope: user_scope)
  filtered_properties = properties.filter do |name, property_schema|
    # 通过 discard_missing 过滤
    next false if user_options[:discard_missing] && !object_value.key?(name.to_s)

    # 通过 locked_exclude 选项过滤
    next false if exclude && exclude.include?(name)

    # 通过 if 选项过滤
    next false unless property_schema.if?(object_value, user_options[:execution])

    # 默认返回 true
    next true
  end

  # 第二步,递归过滤每一个属性
  object = {}
  errors = {}
  cause = nil
  filtered_properties.each do |name, property_schema|
    value = resolve_property_value(object_value, name, property_schema)

    begin
      object[name] = property_schema.filter(value, **user_options, object_value: object_value)
    rescue JsonSchema::ValidationErrors => e
      cause = e.cause || e if cause.nil? # 将第一次出现的错误作为 cause
      errors.merge! e.prepend_root(name).errors
    end
  end.to_h

  # 第三步,检测是否有剩余的属性
  if user_options[:extra_properties] == :raise_error && !(object_value.keys.map(&:to_sym) - properties.keys).empty?
    raise JsonSchema::ValidationError, '遇到多余的属性'
  end

  if errors.empty?
    object
  elsif cause
    begin
      raise cause
    rescue
      raise JsonSchema::ValidationErrors.new(errors)
    end
  else
    raise JsonSchema::ValidationErrors.new(errors)
  end
end

#merge(properties) ⇒ Object



93
94
95
# File 'lib/meta/json_schema/schemas/properties.rb', line 93

def merge(properties)
  self.class.new(@properties.merge(properties.instance_eval { @properties }))
end

#to_swagger_doc(scope: [], stage: nil, **user_options) ⇒ Object

user_options 包括 stage, scope, schema_docs_mapping, defined_scopes_mapping



73
74
75
76
77
78
79
80
81
82
# File 'lib/meta/json_schema/schemas/properties.rb', line 73

def to_swagger_doc(scope: [], stage: nil, **user_options)
  properties = filter_by(stage: stage, user_scope: scope)
  required_keys = properties.filter do |key, property_schema|
    property_schema.options[:required]
  end.keys
  properties = properties.transform_values do |property_schema |
    property_schema.to_schema_doc(stage: stage, scope: scope, **user_options)
  end
  [properties, required_keys]
end

#within(*properties) ⇒ Object



97
98
99
# File 'lib/meta/json_schema/schemas/properties.rb', line 97

def within(*properties)
  self.class.new(@properties.slice(*properties))
end