r2-oas 0.4.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.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +99 -0
  3. data/GEMSPEC.md +20 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.ja.md +271 -0
  6. data/README.md +271 -0
  7. data/lib/r2-oas.rb +35 -0
  8. data/lib/r2-oas/app_configuration.rb +121 -0
  9. data/lib/r2-oas/app_configuration/deprecation.rb +28 -0
  10. data/lib/r2-oas/app_configuration/server.rb +35 -0
  11. data/lib/r2-oas/app_configuration/swagger.rb +35 -0
  12. data/lib/r2-oas/app_configuration/swagger/editor.rb +47 -0
  13. data/lib/r2-oas/app_configuration/swagger/ui.rb +45 -0
  14. data/lib/r2-oas/app_configuration/tool.rb +31 -0
  15. data/lib/r2-oas/app_configuration/tool/paths/stats.rb +43 -0
  16. data/lib/r2-oas/base.rb +48 -0
  17. data/lib/r2-oas/configuration.rb +121 -0
  18. data/lib/r2-oas/configuration/paths_config.rb +44 -0
  19. data/lib/r2-oas/deploy/client.rb +70 -0
  20. data/lib/r2-oas/deploy/swagger-ui/index.html.erb +60 -0
  21. data/lib/r2-oas/dynamic/schema/v3/object/from_routes/hookable_base_object.rb +100 -0
  22. data/lib/r2-oas/errors.rb +13 -0
  23. data/lib/r2-oas/hooks/global_hook.rb +20 -0
  24. data/lib/r2-oas/hooks/hook.rb +79 -0
  25. data/lib/r2-oas/hooks/repository.rb +15 -0
  26. data/lib/r2-oas/lib/core_ext/hash/deep_merge.rb +44 -0
  27. data/lib/r2-oas/lib/core_ext/object/blank.rb +135 -0
  28. data/lib/r2-oas/lib/three-way-merge/twm.rb +83 -0
  29. data/lib/r2-oas/logger/stdout_logger.rb +129 -0
  30. data/lib/r2-oas/pluggable_configuration.rb +36 -0
  31. data/lib/r2-oas/plugin/base.rb +44 -0
  32. data/lib/r2-oas/plugin/executor.rb +148 -0
  33. data/lib/r2-oas/plugin/hookable.rb +42 -0
  34. data/lib/r2-oas/plugin/public.rb +3 -0
  35. data/lib/r2-oas/plugin/transform/transform.rb +10 -0
  36. data/lib/r2-oas/plugin/transform/v3/transform.rb +20 -0
  37. data/lib/r2-oas/plugin/transform/v3/visitable.rb +37 -0
  38. data/lib/r2-oas/public.rb +5 -0
  39. data/lib/r2-oas/routing/adjustor.rb +44 -0
  40. data/lib/r2-oas/routing/base.rb +12 -0
  41. data/lib/r2-oas/routing/components/all.rb +5 -0
  42. data/lib/r2-oas/routing/components/base_component.rb +10 -0
  43. data/lib/r2-oas/routing/components/path_component.rb +67 -0
  44. data/lib/r2-oas/routing/components/request_component.rb +75 -0
  45. data/lib/r2-oas/routing/components/verb_component.rb +21 -0
  46. data/lib/r2-oas/routing/parser.rb +93 -0
  47. data/lib/r2-oas/schema/analyzer.rb +23 -0
  48. data/lib/r2-oas/schema/base.rb +11 -0
  49. data/lib/r2-oas/schema/builder.rb +23 -0
  50. data/lib/r2-oas/schema/cleaner.rb +23 -0
  51. data/lib/r2-oas/schema/editor.rb +146 -0
  52. data/lib/r2-oas/schema/generator.rb +23 -0
  53. data/lib/r2-oas/schema/manager/file/path_item_file_manager.rb +24 -0
  54. data/lib/r2-oas/schema/manager/file_manager.rb +26 -0
  55. data/lib/r2-oas/schema/monitor.rb +52 -0
  56. data/lib/r2-oas/schema/squeezer.rb +23 -0
  57. data/lib/r2-oas/schema/ui.rb +73 -0
  58. data/lib/r2-oas/schema/v3/analyzer.rb +58 -0
  59. data/lib/r2-oas/schema/v3/analyzer/base_analyzer.rb +71 -0
  60. data/lib/r2-oas/schema/v3/analyzer/components/object_analyzer.rb +38 -0
  61. data/lib/r2-oas/schema/v3/analyzer/components_analyzer.rb +30 -0
  62. data/lib/r2-oas/schema/v3/analyzer/path_analyzer.rb +116 -0
  63. data/lib/r2-oas/schema/v3/analyzer/tag_analyzer.rb +38 -0
  64. data/lib/r2-oas/schema/v3/base.rb +28 -0
  65. data/lib/r2-oas/schema/v3/builder.rb +28 -0
  66. data/lib/r2-oas/schema/v3/builder/base_builder.rb +72 -0
  67. data/lib/r2-oas/schema/v3/builder/doc_builder.rb +51 -0
  68. data/lib/r2-oas/schema/v3/cleaner.rb +19 -0
  69. data/lib/r2-oas/schema/v3/cleaner/base_cleaner.rb +30 -0
  70. data/lib/r2-oas/schema/v3/cleaner/components_cleaner.rb +42 -0
  71. data/lib/r2-oas/schema/v3/generator.rb +24 -0
  72. data/lib/r2-oas/schema/v3/generator/base_generator.rb +122 -0
  73. data/lib/r2-oas/schema/v3/generator/components/object_generator.rb +64 -0
  74. data/lib/r2-oas/schema/v3/generator/components/request_body_generator.rb +45 -0
  75. data/lib/r2-oas/schema/v3/generator/components_generator.rb +38 -0
  76. data/lib/r2-oas/schema/v3/generator/doc_generator.rb +115 -0
  77. data/lib/r2-oas/schema/v3/generator/path_generator.rb +78 -0
  78. data/lib/r2-oas/schema/v3/generator/schema_generator.rb +58 -0
  79. data/lib/r2-oas/schema/v3/manager/diff/base_array_diff_manager.rb +60 -0
  80. data/lib/r2-oas/schema/v3/manager/diff/base_diff_manager.rb +29 -0
  81. data/lib/r2-oas/schema/v3/manager/diff/base_hash_diff_manager.rb +95 -0
  82. data/lib/r2-oas/schema/v3/manager/diff/components_diff_manager.rb +19 -0
  83. data/lib/r2-oas/schema/v3/manager/diff/tag_diff_manager.rb +17 -0
  84. data/lib/r2-oas/schema/v3/manager/file/base_file_manager.rb +66 -0
  85. data/lib/r2-oas/schema/v3/manager/file/components_file_manager.rb +22 -0
  86. data/lib/r2-oas/schema/v3/manager/file/include_ref_base_file_manager.rb +89 -0
  87. data/lib/r2-oas/schema/v3/manager/file/path_item_file_manager.rb +22 -0
  88. data/lib/r2-oas/schema/v3/manager/file_manager.rb +12 -0
  89. data/lib/r2-oas/schema/v3/manager/pathname_manager.rb +78 -0
  90. data/lib/r2-oas/schema/v3/object/from_files/base_object.rb +62 -0
  91. data/lib/r2-oas/schema/v3/object/from_files/components/request_body_object.rb +103 -0
  92. data/lib/r2-oas/schema/v3/object/from_files/components/schema_object.rb +102 -0
  93. data/lib/r2-oas/schema/v3/object/from_files/components_object.rb +46 -0
  94. data/lib/r2-oas/schema/v3/object/from_files/external_document_object.rb +23 -0
  95. data/lib/r2-oas/schema/v3/object/from_files/info_object.rb +23 -0
  96. data/lib/r2-oas/schema/v3/object/from_files/openapi_object.rb +61 -0
  97. data/lib/r2-oas/schema/v3/object/from_files/path_item_object.rb +110 -0
  98. data/lib/r2-oas/schema/v3/object/from_files/paths_object.rb +33 -0
  99. data/lib/r2-oas/schema/v3/object/from_files/utils/all.rb +4 -0
  100. data/lib/r2-oas/schema/v3/object/from_files/utils/deep_methods.rb +27 -0
  101. data/lib/r2-oas/schema/v3/object/from_files/utils/refs.rb +151 -0
  102. data/lib/r2-oas/schema/v3/object/from_routes/base_object.rb +75 -0
  103. data/lib/r2-oas/schema/v3/object/from_routes/components/request_body_object.rb +96 -0
  104. data/lib/r2-oas/schema/v3/object/from_routes/components/schema_object.rb +59 -0
  105. data/lib/r2-oas/schema/v3/object/from_routes/components_object.rb +81 -0
  106. data/lib/r2-oas/schema/v3/object/from_routes/external_document_object.rb +28 -0
  107. data/lib/r2-oas/schema/v3/object/from_routes/info_object.rb +43 -0
  108. data/lib/r2-oas/schema/v3/object/from_routes/openapi_object.rb +59 -0
  109. data/lib/r2-oas/schema/v3/object/from_routes/path_item_object.rb +175 -0
  110. data/lib/r2-oas/schema/v3/object/from_routes/paths_object.rb +77 -0
  111. data/lib/r2-oas/schema/v3/object/from_routes/public.rb +9 -0
  112. data/lib/r2-oas/schema/v3/object/from_routes/server_object.rb +21 -0
  113. data/lib/r2-oas/schema/v3/object/from_routes/tag_object.rb +37 -0
  114. data/lib/r2-oas/schema/v3/object/store.rb +54 -0
  115. data/lib/r2-oas/schema/v3/squeezer.rb +29 -0
  116. data/lib/r2-oas/schema/v3/squeezer/base_squeezer.rb +37 -0
  117. data/lib/r2-oas/schema/v3/squeezer/path_squeezer.rb +28 -0
  118. data/lib/r2-oas/schema/v3/squeezer/tag_squeezer.rb +19 -0
  119. data/lib/r2-oas/shared/all.rb +4 -0
  120. data/lib/r2-oas/shared/callable.rb +17 -0
  121. data/lib/r2-oas/shared/sortable.rb +23 -0
  122. data/lib/r2-oas/store.rb +122 -0
  123. data/lib/r2-oas/support/deprecation.rb +24 -0
  124. data/lib/r2-oas/support/deprecation/behavior.rb +21 -0
  125. data/lib/r2-oas/support/deprecation/instance_delegator.rb +42 -0
  126. data/lib/r2-oas/support/deprecation/reporting.rb +91 -0
  127. data/lib/r2-oas/task.rb +11 -0
  128. data/lib/r2-oas/task_logging.rb +41 -0
  129. data/lib/r2-oas/tasks/common.rake +25 -0
  130. data/lib/r2-oas/tasks/main.rake +132 -0
  131. data/lib/r2-oas/tasks/tool.rake +86 -0
  132. data/lib/r2-oas/tool/paths/ls.rb +15 -0
  133. data/lib/r2-oas/tool/paths/stats.rb +84 -0
  134. data/lib/r2-oas/version.rb +5 -0
  135. data/r2-oas.gemspec +48 -0
  136. metadata +415 -0
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'key_flatten'
5
+
6
+ require 'r2-oas/plugin/executor'
7
+ require 'r2-oas/schema/v3/object/store'
8
+
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ module FromFiles
13
+ class BaseObject
14
+ extend Forwardable
15
+
16
+ class << self
17
+ def obj_store
18
+ ::R2OAS::Schema::V3::Store.create(:obj)
19
+ end
20
+ end
21
+
22
+ def_delegators :@plugin_executor, :execute_transform_plugins
23
+
24
+ def initialize(opts = {})
25
+ @opts = opts
26
+ plugins = app_configuration_options[:plugins]
27
+ @plugin_executor = ::R2OAS::Plugin::Executor.new(plugins, opts)
28
+ end
29
+
30
+ def to_doc
31
+ raise 'Implement Inherit Class'
32
+ end
33
+
34
+ private
35
+
36
+ def obj_store
37
+ self.class.obj_store
38
+ end
39
+
40
+ def set_root_doc(root_doc)
41
+ obj_store.root_doc = root_doc.dup
42
+ end
43
+
44
+ def root_doc
45
+ obj_store.root_doc
46
+ end
47
+
48
+ def set_components_name_list(root_doc)
49
+ obj_store.components_schema_name_list = (root_doc.fetch('components', nil)&.fetch('schemas', nil) || {}).keys.sort.uniq
50
+ obj_store.components_request_body_name_list = (root_doc.fetch('components', nil)&.fetch('schemas', nil) || {}).keys.sort.uniq
51
+ end
52
+
53
+ def app_configuration_options
54
+ R2OAS.app_configuration_options
55
+ end
56
+
57
+ attr_accessor :opts
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,103 @@
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 'schema_object'
7
+ require_relative '../utils/all'
8
+
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ module FromFiles
13
+ module Components
14
+ class RequestBodyObject < ::R2OAS::Schema::V3::FromFiles::BaseObject
15
+ include ::R2OAS::Callable
16
+ include DeepMethods
17
+
18
+ def initialize(doc, ref, opts)
19
+ super(opts)
20
+ @doc = doc
21
+ @parent_ref = Components::RequestBodyRef.new(ref)
22
+ resolve_dependencies!
23
+ end
24
+
25
+ def to_doc
26
+ call_ref_path!
27
+
28
+ # MEMO:
29
+ # If it is overwritten, it may lead to unexpected problems, so give a copy
30
+ execute_transform_plugins(:components_request_body, @doc, ref_dup)
31
+ @doc
32
+ end
33
+
34
+ def resolve_dependencies!
35
+ deep_replace!(@doc, '$ref') do |ref_path|
36
+ schema_obj, schema_type, pure_schema_name = ref_path.split('/').slice(1..-1)
37
+ schema_doc = root_doc&.fetch(schema_obj, nil)&.fetch(schema_type, nil)&.fetch(pure_schema_name, nil) || {}
38
+
39
+ ref = create_child_ref(pure_schema_name)
40
+ obj = Components::SchemaObject.new(schema_doc, ref, opts)
41
+
42
+ obj_store.add('components/schemas', pure_schema_name, obj)
43
+ obj
44
+ end
45
+ end
46
+
47
+ def call_ref_path!
48
+ callback = proc { |obj| obj.ref_path }
49
+ deep_call(@doc, '$ref', callback)
50
+ end
51
+
52
+ def schema_name
53
+ return @resolved_schema_name if @resolved_schema_name.present?
54
+
55
+ before_schema_name = ref_dup[:schema_name]
56
+
57
+ _ref_dup = ref_dup
58
+ execute_transform_plugins(:components_request_body_name, _ref_dup)
59
+ @resolved_schema_name = _ref_dup[:schema_name]
60
+
61
+ if before_schema_name != @resolved_schema_name
62
+ if reserved_schema_name_list.include?(@resolved_schema_name)
63
+ raise DepulicateSchemaNameError, "Transformed schema name: '#{@resolved_schema_name}' cannot be used. It already exists."
64
+ else
65
+ obj_store.appended_components_request_body_name_list.push(@resolved_schema_name)
66
+ end
67
+ end
68
+
69
+ @resolved_schema_name
70
+ end
71
+
72
+ def ref_path
73
+ "#/components/requestBodies/#{schema_name}"
74
+ end
75
+
76
+ private
77
+
78
+ def ref_dup
79
+ @parent_ref.dup
80
+ end
81
+
82
+ def reserved_schema_name_list
83
+ (
84
+ obj_store.components_request_body_name_list +
85
+ obj_store.appended_components_request_body_name_list
86
+ ).uniq
87
+ end
88
+
89
+ def create_child_ref(schema_name)
90
+ local_ref_hash = ref_dup.to_h
91
+ parent_schema_name = local_ref_hash[:schema_name]
92
+ depth = local_ref_hash[:depth] + 1
93
+ ref_data = local_ref_hash.merge({ from: :request_body, schema_name: schema_name, parent_schema_name: parent_schema_name, depth: depth })
94
+ ref = Components::SchemaRef.new(ref_data)
95
+ ref.send(:parent=, ref_dup)
96
+ ref
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -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