Class: Meta::JsonSchema::Properties

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

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



87
88
89
# File 'lib/meta/json_schema/schemas/properties.rb', line 87

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

Instance Method Details

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



14
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
# File 'lib/meta/json_schema/schemas/properties.rb', line 14

def filter(object_value, user_options = {})
  # 第一步,根据 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?(user_options)

    # 默认返回 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



83
84
85
# File 'lib/meta/json_schema/schemas/properties.rb', line 83

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

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



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/meta/json_schema/schemas/properties.rb', line 68

def to_swagger_doc(scope: [], stage: nil, **user_options)
  locked_scopes = scope
  properties = filter_by(stage: stage, user_scope: locked_scopes)
  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