r2-oas 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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