r2-oas 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/GEMSPEC.md +4 -3
  4. data/README.ja.md +54 -37
  5. data/README.md +50 -31
  6. data/lib/r2-oas.rb +5 -7
  7. data/lib/r2-oas/app_configuration.rb +17 -1
  8. data/lib/r2-oas/app_configuration/deprecation.rb +28 -0
  9. data/lib/r2-oas/configuration.rb +52 -0
  10. data/lib/r2-oas/deploy/client.rb +21 -6
  11. data/lib/r2-oas/{plugins/schema/v3/object → dynamic/schema/v3/object/from_routes}/hookable_base_object.rb +7 -7
  12. data/lib/r2-oas/errors.rb +5 -0
  13. data/lib/r2-oas/hooks/hook.rb +7 -5
  14. data/lib/r2-oas/lib/core_ext/hash/deep_merge.rb +44 -0
  15. data/lib/r2-oas/lib/core_ext/object/blank.rb +135 -0
  16. data/lib/r2-oas/pluggable_configuration.rb +8 -5
  17. data/lib/r2-oas/plugin/base.rb +44 -0
  18. data/lib/r2-oas/plugin/executor.rb +148 -0
  19. data/lib/r2-oas/plugin/hookable.rb +42 -0
  20. data/lib/r2-oas/plugin/public.rb +3 -0
  21. data/lib/r2-oas/plugin/transform/transform.rb +10 -0
  22. data/lib/r2-oas/plugin/transform/v3/transform.rb +20 -0
  23. data/lib/r2-oas/plugin/transform/v3/visitable.rb +37 -0
  24. data/lib/r2-oas/public.rb +5 -0
  25. data/lib/r2-oas/schema/base.rb +1 -1
  26. data/lib/r2-oas/schema/builder.rb +1 -1
  27. data/lib/r2-oas/schema/editor.rb +8 -1
  28. data/lib/r2-oas/schema/v3/analyzer/path_analyzer.rb +1 -1
  29. data/lib/r2-oas/schema/v3/builder.rb +1 -1
  30. data/lib/r2-oas/schema/v3/builder/base_builder.rb +14 -2
  31. data/lib/r2-oas/schema/v3/builder/doc_builder.rb +10 -2
  32. data/lib/r2-oas/schema/v3/generator/base_generator.rb +7 -2
  33. data/lib/r2-oas/schema/v3/generator/doc_generator.rb +1 -1
  34. data/lib/r2-oas/schema/v3/manager/file/include_ref_base_file_manager.rb +3 -2
  35. data/lib/r2-oas/schema/v3/object/from_files/base_object.rb +62 -0
  36. data/lib/r2-oas/schema/v3/object/from_files/components/request_body_object.rb +103 -0
  37. data/lib/r2-oas/schema/v3/object/from_files/components/schema_object.rb +102 -0
  38. data/lib/r2-oas/schema/v3/object/from_files/components_object.rb +46 -0
  39. data/lib/r2-oas/schema/v3/object/from_files/external_document_object.rb +23 -0
  40. data/lib/r2-oas/schema/v3/object/from_files/info_object.rb +23 -0
  41. data/lib/r2-oas/schema/v3/object/from_files/openapi_object.rb +61 -0
  42. data/lib/r2-oas/schema/v3/object/from_files/path_item_object.rb +110 -0
  43. data/lib/r2-oas/schema/v3/object/from_files/paths_object.rb +33 -0
  44. data/lib/r2-oas/schema/v3/object/from_files/utils/all.rb +4 -0
  45. data/lib/r2-oas/schema/v3/object/from_files/utils/deep_methods.rb +27 -0
  46. data/lib/r2-oas/schema/v3/object/from_files/utils/refs.rb +151 -0
  47. data/lib/r2-oas/schema/v3/object/{base_object.rb → from_routes/base_object.rb} +11 -1
  48. data/lib/r2-oas/schema/v3/object/{components → from_routes/components}/request_body_object.rb +23 -19
  49. data/lib/r2-oas/schema/v3/object/{components → from_routes/components}/schema_object.rb +16 -12
  50. data/lib/r2-oas/schema/v3/object/{components_object.rb → from_routes/components_object.rb} +11 -11
  51. data/lib/r2-oas/schema/v3/object/from_routes/external_document_object.rb +28 -0
  52. data/lib/r2-oas/schema/v3/object/{info_object.rb → from_routes/info_object.rb} +11 -2
  53. data/lib/r2-oas/schema/v3/object/{openapi_object.rb → from_routes/openapi_object.rb} +12 -11
  54. data/lib/r2-oas/schema/v3/object/{path_item_object.rb → from_routes/path_item_object.rb} +6 -6
  55. data/lib/r2-oas/schema/v3/object/{paths_object.rb → from_routes/paths_object.rb} +11 -8
  56. data/lib/r2-oas/schema/v3/object/{public.rb → from_routes/public.rb} +0 -0
  57. data/lib/r2-oas/schema/v3/object/{server_object.rb → from_routes/server_object.rb} +0 -0
  58. data/lib/r2-oas/schema/v3/object/{tag_object.rb → from_routes/tag_object.rb} +2 -1
  59. data/lib/r2-oas/schema/v3/object/store.rb +54 -0
  60. data/lib/r2-oas/shared/all.rb +1 -0
  61. data/lib/r2-oas/shared/callable.rb +17 -0
  62. data/lib/r2-oas/store.rb +20 -16
  63. data/lib/r2-oas/support/deprecation.rb +24 -0
  64. data/lib/r2-oas/support/deprecation/behavior.rb +21 -0
  65. data/lib/r2-oas/support/deprecation/instance_delegator.rb +42 -0
  66. data/lib/r2-oas/support/deprecation/reporting.rb +91 -0
  67. data/lib/r2-oas/task_logging.rb +3 -7
  68. data/lib/r2-oas/tasks/common.rake +1 -2
  69. data/lib/r2-oas/tasks/main.rake +31 -9
  70. data/lib/r2-oas/tasks/tool.rake +16 -6
  71. data/lib/r2-oas/version.rb +1 -1
  72. data/r2-oas.gemspec +3 -5
  73. metadata +70 -81
  74. data/.github/ISSUE_TEMPLATE.md +0 -12
  75. data/.github/PULL_REQUEST_TEMPLATE.md +0 -12
  76. data/.gitignore +0 -16
  77. data/.rspec +0 -3
  78. data/.rubocop.yml +0 -10
  79. data/.rubocop_todo.yml +0 -282
  80. data/.travis.yml +0 -26
  81. data/Appraisals +0 -13
  82. data/CODE_OF_CONDUCT.md +0 -74
  83. data/Gemfile +0 -12
  84. data/Rakefile +0 -8
  85. data/bin/console +0 -12
  86. data/bin/setup +0 -8
  87. data/devscript/all_support_ruby.sh +0 -43
  88. data/devscript/bundle_for_all_support_ruby.sh +0 -31
  89. data/devscript/rspec_for_all_support_ruby.sh +0 -27
  90. data/docs/.nojekyll +0 -0
  91. data/docs/README.md +0 -173
  92. data/docs/_sidebar.md +0 -25
  93. data/docs/attention/if_clash.md +0 -17
  94. data/docs/index.html +0 -29
  95. data/docs/schema/3.0.0.md +0 -155
  96. data/docs/setting/COC.md +0 -14
  97. data/docs/setting/CORS.md +0 -22
  98. data/docs/setting/configure.md +0 -176
  99. data/docs/trableshouting/runtime_error.md +0 -44
  100. data/docs/usage/analyze_docs.md +0 -875
  101. data/docs/usage/clean_docs.md +0 -19
  102. data/docs/usage/deploy_docs.md +0 -839
  103. data/docs/usage/display_paths_list.md +0 -35
  104. data/docs/usage/display_paths_stats.md +0 -54
  105. data/docs/usage/edit_docs.md +0 -218
  106. data/docs/usage/generate_docs.md +0 -412
  107. data/docs/usage/monitor_docs.md +0 -219
  108. data/docs/usage/use_hook_methods.md +0 -236
  109. data/docs/usage/use_hook_to_generate_docs.md +0 -235
  110. data/docs/usage/use_schema_namespace.md +0 -181
  111. data/docs/usage/use_tag_namespace.md +0 -180
  112. data/docs/usage/view_docs.md +0 -262
  113. data/gemfiles/ruby_2.3.3.gemfile +0 -11
  114. data/gemfiles/ruby_2.4.2.gemfile +0 -11
  115. data/gemfiles/ruby_2.5.8.gemfile +0 -11
  116. data/gemfiles/ruby_2.6.6.gemfile +0 -11
  117. data/gemfiles/ruby_2.7.1.gemfile +0 -11
  118. data/lib/r2-oas/deploy/swagger-ui/dist/favicon-16x16.png +0 -0
  119. data/lib/r2-oas/deploy/swagger-ui/dist/favicon-32x32.png +0 -0
  120. data/lib/r2-oas/deploy/swagger-ui/dist/oauth2-redirect.html +0 -68
  121. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-bundle.js +0 -134
  122. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-bundle.js.map +0 -1
  123. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-standalone-preset.js +0 -22
  124. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-standalone-preset.js.map +0 -1
  125. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.css +0 -4
  126. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.css.map +0 -1
  127. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.js +0 -9
  128. data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.js.map +0 -1
  129. data/lib/r2-oas/schema/v3/object/external_document_object.rb +0 -19
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/shared/callable'
4
+ require 'r2-oas/errors'
5
+ require_relative '../base_object'
6
+ require_relative '../utils/all'
7
+
8
+ module R2OAS
9
+ module Schema
10
+ module V3
11
+ module FromFiles
12
+ module Components
13
+ class SchemaObject < ::R2OAS::Schema::V3::FromFiles::BaseObject
14
+ include ::R2OAS::Callable
15
+ include DeepMethods
16
+
17
+ def initialize(doc, ref, opts)
18
+ super(opts)
19
+ @doc = doc
20
+ @parent_ref = Components::SchemaRef.new(ref)
21
+ resolve_dependencies!
22
+ end
23
+
24
+ def to_doc
25
+ call_ref_path!
26
+
27
+ # MEMO:
28
+ # If it is overwritten, it may lead to unexpected problems, so give a copy
29
+ execute_transform_plugins(:components_schema, @doc, ref_dup)
30
+ @doc
31
+ end
32
+
33
+ def resolve_dependencies!
34
+ deep_replace!(@doc, '$ref') do |ref_path|
35
+ schema_obj, schema_type, pure_schema_name = ref_path.split('/').slice(1..-1)
36
+ schema_doc = root_doc&.fetch(schema_obj, nil)&.fetch(schema_type, nil)&.fetch(pure_schema_name, nil) || {}
37
+
38
+ ref = create_child_ref(pure_schema_name)
39
+ obj = Components::SchemaObject.new(schema_doc, ref, opts)
40
+
41
+ obj_store.add('components/schemas', pure_schema_name, obj)
42
+ obj
43
+ end
44
+ end
45
+
46
+ def call_ref_path!
47
+ callback = proc { |obj| obj.ref_path }
48
+ deep_call(@doc, '$ref', callback)
49
+ end
50
+
51
+ def schema_name
52
+ return @resolved_schema_name if @resolved_schema_name.present?
53
+
54
+ before_schema_name = ref_dup[:schema_name]
55
+
56
+ _ref_dup = ref_dup
57
+ execute_transform_plugins(:components_schema_name, _ref_dup)
58
+ @resolved_schema_name = _ref_dup[:schema_name]
59
+
60
+ if before_schema_name != @resolved_schema_name
61
+ if reserved_schema_name_list.include?(@resolved_schema_name)
62
+ raise DepulicateSchemaNameError, "Transformed schema name: '#{@resolved_schema_name}' cannot be used. It already exists."
63
+ else
64
+ obj_store.appended_components_schema_name_list.push(@resolved_schema_name)
65
+ end
66
+ end
67
+
68
+ @resolved_schema_name
69
+ end
70
+
71
+ def ref_path
72
+ "#/components/schemas/#{schema_name}"
73
+ end
74
+
75
+ private
76
+
77
+ def ref_dup
78
+ @parent_ref.dup
79
+ end
80
+
81
+ def reserved_schema_name_list
82
+ (
83
+ obj_store.components_schema_name_list +
84
+ obj_store.appended_components_schema_name_list
85
+ ).uniq
86
+ end
87
+
88
+ def create_child_ref(schema_name)
89
+ local_ref_hash = ref_dup.to_h
90
+ parent_schema_name = local_ref_hash[:schema_name]
91
+ depth = local_ref_hash[:depth] + 1
92
+ ref_data = local_ref_hash.merge({ from: :schema, schema_name: schema_name, parent_schema_name: parent_schema_name, depth: depth })
93
+ ref = Components::SchemaRef.new(ref_data)
94
+ ref.send(:parent=, ref_dup)
95
+ ref
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_object'
4
+ require_relative 'components/schema_object'
5
+ require_relative 'components/request_body_object'
6
+
7
+ module R2OAS
8
+ module Schema
9
+ module V3
10
+ module FromFiles
11
+ class ComponentsObject < BaseObject
12
+ def initialize(doc, opts = {})
13
+ super(opts)
14
+ @doc = doc
15
+ end
16
+
17
+ def to_doc
18
+ create_doc
19
+ @doc
20
+ end
21
+
22
+ private
23
+
24
+ def create_doc
25
+ create_components_schema_docs!
26
+ create_components_request_body_docs!
27
+ end
28
+
29
+ def create_components_schema_docs!
30
+ result = obj_store.gets('components/schemas').each_with_object({}) do |obj, data|
31
+ data[obj.schema_name] = obj.to_doc
32
+ end
33
+ @doc.merge!('schemas' => result) if result.present?
34
+ end
35
+
36
+ def create_components_request_body_docs!
37
+ result = obj_store.gets('components/requestBodies').each_with_object({}) do |obj, data|
38
+ data[obj.schema_name] = obj.to_doc
39
+ end
40
+ @doc.merge!('requestBodies' => result) if result.present?
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_object'
4
+
5
+ module R2OAS
6
+ module Schema
7
+ module V3
8
+ module FromFiles
9
+ class ExternalDocumentObject < BaseObject
10
+ def initialize(doc, opts = {})
11
+ super(opts)
12
+ @doc = doc
13
+ end
14
+
15
+ def to_doc
16
+ execute_transform_plugins(:external_document, @doc)
17
+ @doc
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_object'
4
+
5
+ module R2OAS
6
+ module Schema
7
+ module V3
8
+ module FromFiles
9
+ class InfoObject < BaseObject
10
+ def initialize(doc, opts = {})
11
+ super(opts)
12
+ @doc = doc
13
+ end
14
+
15
+ def to_doc
16
+ execute_transform_plugins(:info, @doc)
17
+ @doc
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_object'
4
+ require_relative 'info_object'
5
+ require_relative 'paths_object'
6
+ require_relative 'external_document_object'
7
+ require_relative 'components_object'
8
+
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ module FromFiles
13
+ class OpenapiObject < BaseObject
14
+ def initialize(doc, opts = {})
15
+ super(opts)
16
+ @doc = doc
17
+ set_root_doc(doc)
18
+ set_components_name_list(doc)
19
+ end
20
+
21
+ def to_doc
22
+ execute_transform_plugins(:setup)
23
+ # MEMO:
24
+ # Make sure paths_doc is run first
25
+ # This is because the components object is stored in the store by executing paths_doc
26
+ # and it is looped to generate the component document.
27
+ result = {
28
+ 'openapi' => '3.0.0',
29
+ 'info' => info_doc,
30
+ 'tags' => @doc['tags'],
31
+ 'paths' => paths_doc,
32
+ 'externalDocs' => external_docs_doc,
33
+ 'servers' => @doc['servers'],
34
+ 'components' => components_doc
35
+ }
36
+ execute_transform_plugins(:teardown)
37
+ result
38
+ end
39
+
40
+ private
41
+
42
+ def info_doc
43
+ InfoObject.new(@doc['info'], @opts).to_doc
44
+ end
45
+
46
+ def paths_doc
47
+ PathsObject.new(@doc['paths'], @opts).to_doc
48
+ end
49
+
50
+ def external_docs_doc
51
+ ExternalDocumentObject.new(@doc['externalDocs'], @opts).to_doc
52
+ end
53
+
54
+ def components_doc
55
+ ComponentsObject.new(@doc['components'], @opts).to_doc
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/shared/callable'
4
+ require_relative 'base_object'
5
+ require_relative 'components/schema_object'
6
+ require_relative 'components/request_body_object'
7
+ require_relative 'utils/all'
8
+
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ module FromFiles
13
+ class PathItemObject < BaseObject
14
+ include ::R2OAS::Callable
15
+ include DeepMethods
16
+
17
+ def initialize(doc, ref, opts = {})
18
+ super(opts)
19
+ @doc = doc
20
+ @parent_ref = PathRef.new(ref)
21
+ resolve_dependencies!
22
+ end
23
+
24
+ def to_doc
25
+ call_ref_path!
26
+
27
+ # MEMO:
28
+ # If it is overwritten, it may lead to unexpected problems, so give a copy
29
+ execute_transform_plugins(:path_item, @doc, ref_dup)
30
+ @doc
31
+ end
32
+
33
+ # Breaking changes to @doc
34
+ def resolve_dependencies!
35
+ local_ref_hash = ref_dup.to_h
36
+
37
+ @doc.each do |verb, data_when_verb|
38
+ local_ref_hash[:verb] = verb
39
+ local_ref_hash[:tag_name] = data_when_verb['tags'].first
40
+
41
+ resolve_dependencies_at_schema!(@doc, verb, data_when_verb, local_ref_hash)
42
+ resolve_dependencies_at_request_body!(@doc, verb, data_when_verb, local_ref_hash)
43
+ end
44
+ end
45
+
46
+ def call_ref_path!
47
+ callback = proc { |obj| obj.ref_path }
48
+ deep_call(@doc, '$ref', callback)
49
+ end
50
+
51
+ private
52
+
53
+ def ref_dup
54
+ @parent_ref.dup
55
+ end
56
+
57
+ def resolve_dependencies_at_schema!(data, verb, data_when_verb, local_ref_hash)
58
+ data_when_verb['responses'].each do |http_status, data_when_http_status|
59
+ local_ref_hash[:http_status] = http_status
60
+
61
+ deep_replace!(data_when_http_status, '$ref') do |ref_path|
62
+ schema_obj, schema_type, schema_name = ref_path.split('/').slice(1..-1)
63
+ schema_doc = root_doc&.fetch(schema_obj, nil)&.fetch(schema_type, nil)&.fetch(schema_name, nil) || {}
64
+
65
+ ref = create_child_schema_ref(schema_name, local_ref_hash)
66
+ obj = Components::SchemaObject.new(schema_doc, ref, opts)
67
+
68
+ obj_store.add('components/schemas', schema_name, obj)
69
+ obj
70
+ end
71
+
72
+ data[verb]['responses'][http_status] = data_when_http_status
73
+ end
74
+ end
75
+
76
+ def resolve_dependencies_at_request_body!(data, verb, data_when_verb, local_ref_hash)
77
+ deep_replace!(data_when_verb['requestBody'], '$ref') do |ref_path|
78
+ schema_obj, schema_type, schema_name = ref_path.split('/').slice(1..-1)
79
+ schema_doc = root_doc&.fetch(schema_obj, nil)&.fetch(schema_type, nil)&.fetch(schema_name, nil) || {}
80
+
81
+ ref = create_child_request_body_ref(schema_name, local_ref_hash)
82
+ obj = Components::RequestBodyObject.new(schema_doc, ref, opts)
83
+
84
+ obj_store.add('components/requestBodies', schema_name, obj)
85
+
86
+ data[verb]['requestBody']['$ref'] = obj
87
+ obj
88
+ end
89
+ end
90
+
91
+ def create_child_schema_ref(schema_name, local_ref_hash)
92
+ local_ref_hash_dup = local_ref_hash.dup
93
+ ref_data = local_ref_hash_dup.merge({ from: :path_item, schema_name: schema_name, depth: 0 })
94
+ ref = Components::SchemaRef.new(ref_data)
95
+ end
96
+
97
+ def create_child_request_body_ref(schema_name, local_ref_hash)
98
+ local_ref_hash_dup = local_ref_hash.dup
99
+ # MEMO:
100
+ # requestBody does not depend on http_status
101
+ local_ref_hash_dup.delete(:http_status)
102
+
103
+ ref_data = local_ref_hash_dup.merge({ from: :path_item, schema_name: schema_name, depth: 0 })
104
+ ref = Components::RequestBodyRef.new(ref_data)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_object'
4
+ require_relative 'path_item_object'
5
+
6
+ module R2OAS
7
+ module Schema
8
+ module V3
9
+ module FromFiles
10
+ class PathsObject < BaseObject
11
+ def initialize(doc, opts = {})
12
+ super(opts)
13
+ @doc = doc
14
+ end
15
+
16
+ def to_doc
17
+ create_doc
18
+ @doc
19
+ end
20
+
21
+ private
22
+
23
+ def create_doc
24
+ @doc.each do |path, doc_when_path|
25
+ ref = { path: path }
26
+ @doc[path] = PathItemObject.new(doc_when_path, ref, opts).to_doc
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'deep_methods'
4
+ require_relative 'refs'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module R2OAS
4
+ module Schema
5
+ module V3
6
+ module FromFiles
7
+ module DeepMethods
8
+ def deep_replace!(data, target, &blk)
9
+ return unless data.is_a?(Hash)
10
+
11
+ data.each do |key, value|
12
+ if key.eql? target
13
+ # MEMO:
14
+ # When using the same schema, it has already been replaced by an object
15
+ if value.is_a?(String)
16
+ data[key] = block_given? ? yield(value) : value
17
+ end
18
+ else
19
+ deep_replace!(value, target, &blk)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/errors'
4
+
5
+ module R2OAS
6
+ module Schema
7
+ module V3
8
+ module FromFiles
9
+ class BaseRef
10
+ def pretty_print(q)
11
+ pp_hash(q, to_h)
12
+ end
13
+
14
+ attr_reader :parent
15
+
16
+ def []=(key, value)
17
+ if writable_keys.include?(key)
18
+ send(:"#{key}=", value)
19
+ value
20
+ else
21
+ display_key = key.is_a?(Symbol) ? ":#{key}" : key
22
+ raise ::R2OAS::RefInvalidAssignment, "invalid method `[#{display_key}]=' called for #{self}"
23
+ end
24
+ end
25
+
26
+ def [](key)
27
+ send(key)
28
+ end
29
+
30
+ def to_h
31
+ valid_keys.each_with_object({}) do |key, result|
32
+ result[key] = send(key)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # MEMO:
39
+ # https://apidock.com/ruby/v1_9_3_392/PP/PPMethods/pp_hash
40
+ def pp_hash(q, obj)
41
+ q.group(1, '{', '}') do
42
+ q.seplist(obj, nil, :each_pair) do |k, v|
43
+ q.group do
44
+ q.pp k
45
+ q.text '=>'
46
+ q.group(1) do
47
+ q.breakable ''
48
+ q.pp v
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def build(ref_or_data, merge_data = {})
56
+ data = ref_or_data.to_h.merge(merge_data)
57
+ data.keys.each do |key|
58
+ instance_variable_set(:"@#{key}", data[key])
59
+ end
60
+
61
+ @parent = ref_or_data if ref_or_data.respond_to?(:parent)
62
+ end
63
+
64
+ attr_writer :parent
65
+
66
+ def valid_keys
67
+ raise NoImplementError, 'Please implement in inherited class.'
68
+ end
69
+
70
+ def writable_keys
71
+ raise NoImplementError, 'Please implement in inherited class.'
72
+ end
73
+ end
74
+
75
+ class PathRef < BaseRef
76
+ VALID_KEYS = %i[type path].freeze
77
+
78
+ attr_reader(*VALID_KEYS)
79
+
80
+ def initialize(data)
81
+ build(data, { type: :path_item })
82
+ end
83
+
84
+ private
85
+
86
+ attr_writer(*VALID_KEYS)
87
+
88
+ def valid_keys
89
+ VALID_KEYS
90
+ end
91
+
92
+ def writable_keys
93
+ []
94
+ end
95
+ end
96
+
97
+ module Components
98
+ class SchemaRef < BaseRef
99
+ READONLY_KEYS = %i[type path parent_schema_name depth tag_name verb http_status from].freeze
100
+ WRITABLE_KEYS = [:schema_name].freeze
101
+ VALID_KEYS = READONLY_KEYS + WRITABLE_KEYS
102
+
103
+ attr_reader(*VALID_KEYS)
104
+ attr_writer(*WRITABLE_KEYS)
105
+
106
+ def initialize(ref_or_data)
107
+ build(ref_or_data, { type: :schema })
108
+ end
109
+
110
+ private
111
+
112
+ attr_writer(*READONLY_KEYS)
113
+
114
+ def valid_keys
115
+ VALID_KEYS
116
+ end
117
+
118
+ def writable_keys
119
+ WRITABLE_KEYS
120
+ end
121
+ end
122
+
123
+ class RequestBodyRef < BaseRef
124
+ READONLY_KEYS = %i[type path parent_schema_name depth tag_name verb from].freeze
125
+ WRITABLE_KEYS = [:schema_name].freeze
126
+ VALID_KEYS = READONLY_KEYS + WRITABLE_KEYS
127
+
128
+ attr_accessor(*VALID_KEYS)
129
+ attr_writer(*WRITABLE_KEYS)
130
+
131
+ def initialize(ref_or_data)
132
+ build(ref_or_data, { type: :request_body })
133
+ end
134
+
135
+ private
136
+
137
+ attr_writer(*READONLY_KEYS)
138
+
139
+ def valid_keys
140
+ VALID_KEYS
141
+ end
142
+
143
+ def writable_keys
144
+ WRITABLE_KEYS
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end