Class: Liminal::Dialects::OpenAPI30

Inherits:
Object
  • Object
show all
Defined in:
lib/liminal/dialects/openapi_30.rb,
lib/liminal/dialects/openapi_30/metadata_validator.rb

Overview

OpenAPI 3.0-specific schema behavior and validation.

Defined Under Namespace

Classes: InvalidFragmentError, UnsupportedPatternError

Constant Summary collapse

NAME =
:openapi_3_0
TYPES =
%w[array boolean integer number object string].freeze
KEYWORD_ORDER =
%w[
  $ref title type format nullable description properties required items
  enum minimum exclusiveMinimum maximum exclusiveMaximum multipleOf
  minLength maxLength pattern minItems maxItems uniqueItems minProperties
  maxProperties additionalProperties allOf oneOf anyOf not default example
  readOnly writeOnly deprecated discriminator xml externalDocs
].freeze
ALLOWED_KEYWORDS =
KEYWORD_ORDER.to_set.freeze
SCHEMA_ARRAY_KEYWORDS =
%w[allOf oneOf anyOf].freeze
NUMERIC_KEYWORDS =
%w[maximum minimum].freeze
SIZE_KEYWORDS =
%w[maxLength minLength maxItems minItems maxProperties minProperties].freeze
BOOLEAN_KEYWORDS =
%w[exclusiveMaximum exclusiveMinimum uniqueItems nullable readOnly writeOnly deprecated].freeze
STRING_KEYWORDS =
%w[$ref title description format pattern].freeze
RUBY_ONLY_PATTERN_TOKENS =
[
  /\\[CEGHhKMNOPRXYZegky]/,
  /\\[ghk]<|\\k'/,
  /\\[pP]\{/,
  /\\u\{/,
  /\[\[:/,
  /\[[^\]]*&&/,
  /\(\?>|\(\?#|\(\?~|\(\?\(|\(\?<=[^)]|\(\?<!/,
  /\(\?<[^=!]|\(\?'/,
  /\(\?[imx-]+[:)]/,
  /(?:\*|\+|\?|\{[^}]+\})\+/
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeOpenAPI30

Returns a new instance of OpenAPI30.



46
47
48
# File 'lib/liminal/dialects/openapi_30.rb', line 46

def initialize
  @name = NAME
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



44
45
46
# File 'lib/liminal/dialects/openapi_30.rb', line 44

def name
  @name
end

Instance Method Details

#nullable(fragment) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'lib/liminal/dialects/openapi_30.rb', line 50

def nullable(fragment)
  if fragment.key?("type")
    fragment.merge("nullable" => true)
  elsif fragment.key?("anyOf") && fragment.keys == ["anyOf"]
    {"anyOf" => fragment.fetch("anyOf").map { |alternative| nullable(alternative) }}
  else
    raise InvalidFragmentError,
          "nullable schemas require an explicit type in the same Schema Object"
  end
end

#order(schema) ⇒ Object

Produce stable keyword ordering while preserving deterministic property order from the dry-schema AST.



85
86
87
# File 'lib/liminal/dialects/openapi_30.rb', line 85

def order(schema)
  order_schema(schema)
end

#pattern(regexp) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/liminal/dialects/openapi_30.rb', line 61

def pattern(regexp)
  raise UnsupportedPatternError, "expected a Ruby Regexp" unless regexp.is_a?(Regexp)
  raise UnsupportedPatternError, "Ruby regular-expression options are not supported" unless regexp.options.zero?

  source = regexp.source
  if ruby_line_anchor?(source)
    raise UnsupportedPatternError,
          "Ruby ^ and $ line anchors are not safely ECMA-262-compatible; use \\A and \\z"
  end
  if RUBY_ONLY_PATTERN_TOKENS.any? { |token| token.match?(source) }
    raise UnsupportedPatternError, "the Ruby regular expression is not safely ECMA-262-compatible"
  end

  translate_anchors(source)
end

#validate!(schema) ⇒ Object

Validate a recursively string-keyed Schema Object fragment.



78
79
80
81
# File 'lib/liminal/dialects/openapi_30.rb', line 78

def validate!(schema)
  validate_schema!(schema)
  schema
end