apiwork 0.0.0.pre → 0.1.2

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +2 -2
  3. data/README.md +117 -1
  4. data/Rakefile +5 -3
  5. data/app/controllers/apiwork/errors_controller.rb +13 -0
  6. data/app/controllers/apiwork/exports_controller.rb +22 -0
  7. data/lib/apiwork/abstractable.rb +26 -0
  8. data/lib/apiwork/adapter/base.rb +369 -0
  9. data/lib/apiwork/adapter/builder/api/base.rb +66 -0
  10. data/lib/apiwork/adapter/builder/contract/base.rb +86 -0
  11. data/lib/apiwork/adapter/capability/api/base.rb +51 -0
  12. data/lib/apiwork/adapter/capability/api/scope.rb +64 -0
  13. data/lib/apiwork/adapter/capability/base.rb +291 -0
  14. data/lib/apiwork/adapter/capability/contract/base.rb +37 -0
  15. data/lib/apiwork/adapter/capability/contract/scope.rb +110 -0
  16. data/lib/apiwork/adapter/capability/operation/base.rb +172 -0
  17. data/lib/apiwork/adapter/capability/operation/metadata_shape.rb +165 -0
  18. data/lib/apiwork/adapter/capability/result.rb +21 -0
  19. data/lib/apiwork/adapter/capability/runner.rb +56 -0
  20. data/lib/apiwork/adapter/capability/transformer/request/base.rb +72 -0
  21. data/lib/apiwork/adapter/capability/transformer/response/base.rb +45 -0
  22. data/lib/apiwork/adapter/registry.rb +16 -0
  23. data/lib/apiwork/adapter/serializer/error/base.rb +72 -0
  24. data/lib/apiwork/adapter/serializer/error/default/api_builder.rb +32 -0
  25. data/lib/apiwork/adapter/serializer/error/default.rb +37 -0
  26. data/lib/apiwork/adapter/serializer/resource/base.rb +84 -0
  27. data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +209 -0
  28. data/lib/apiwork/adapter/serializer/resource/default.rb +39 -0
  29. data/lib/apiwork/adapter/standard/capability/filtering/api_builder.rb +75 -0
  30. data/lib/apiwork/adapter/standard/capability/filtering/constants.rb +37 -0
  31. data/lib/apiwork/adapter/standard/capability/filtering/contract_builder.rb +193 -0
  32. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/builder.rb +47 -0
  33. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/operator_builder.rb +36 -0
  34. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter.rb +462 -0
  35. data/lib/apiwork/adapter/standard/capability/filtering/operation.rb +22 -0
  36. data/lib/apiwork/adapter/standard/capability/filtering/request_transformer.rb +47 -0
  37. data/lib/apiwork/adapter/standard/capability/filtering.rb +18 -0
  38. data/lib/apiwork/adapter/standard/capability/including/contract_builder.rb +169 -0
  39. data/lib/apiwork/adapter/standard/capability/including/operation.rb +20 -0
  40. data/lib/apiwork/adapter/standard/capability/including.rb +16 -0
  41. data/lib/apiwork/adapter/standard/capability/pagination/api_builder.rb +34 -0
  42. data/lib/apiwork/adapter/standard/capability/pagination/contract_builder.rb +35 -0
  43. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/cursor.rb +84 -0
  44. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/offset.rb +66 -0
  45. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate.rb +24 -0
  46. data/lib/apiwork/adapter/standard/capability/pagination/operation.rb +24 -0
  47. data/lib/apiwork/adapter/standard/capability/pagination.rb +21 -0
  48. data/lib/apiwork/adapter/standard/capability/sorting/api_builder.rb +19 -0
  49. data/lib/apiwork/adapter/standard/capability/sorting/contract_builder.rb +84 -0
  50. data/lib/apiwork/adapter/standard/capability/sorting/operation/sort.rb +83 -0
  51. data/lib/apiwork/adapter/standard/capability/sorting/operation.rb +22 -0
  52. data/lib/apiwork/adapter/standard/capability/sorting.rb +17 -0
  53. data/lib/apiwork/adapter/standard/capability/writing/constants.rb +15 -0
  54. data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +253 -0
  55. data/lib/apiwork/adapter/standard/capability/writing/operation/issue_mapper.rb +210 -0
  56. data/lib/apiwork/adapter/standard/capability/writing/operation.rb +32 -0
  57. data/lib/apiwork/adapter/standard/capability/writing/request_transformer.rb +37 -0
  58. data/lib/apiwork/adapter/standard/capability/writing.rb +17 -0
  59. data/lib/apiwork/adapter/standard/includes_resolver.rb +106 -0
  60. data/lib/apiwork/adapter/standard.rb +22 -0
  61. data/lib/apiwork/adapter/wrapper/base.rb +70 -0
  62. data/lib/apiwork/adapter/wrapper/collection/base.rb +60 -0
  63. data/lib/apiwork/adapter/wrapper/collection/default.rb +47 -0
  64. data/lib/apiwork/adapter/wrapper/error/base.rb +30 -0
  65. data/lib/apiwork/adapter/wrapper/error/default.rb +34 -0
  66. data/lib/apiwork/adapter/wrapper/member/base.rb +58 -0
  67. data/lib/apiwork/adapter/wrapper/member/default.rb +40 -0
  68. data/lib/apiwork/adapter/wrapper/shape.rb +203 -0
  69. data/lib/apiwork/adapter.rb +50 -0
  70. data/lib/apiwork/api/base.rb +802 -0
  71. data/lib/apiwork/api/element.rb +110 -0
  72. data/lib/apiwork/api/enum_registry/definition.rb +51 -0
  73. data/lib/apiwork/api/enum_registry.rb +98 -0
  74. data/lib/apiwork/api/info/contact.rb +67 -0
  75. data/lib/apiwork/api/info/license.rb +50 -0
  76. data/lib/apiwork/api/info/server.rb +50 -0
  77. data/lib/apiwork/api/info.rb +221 -0
  78. data/lib/apiwork/api/object.rb +235 -0
  79. data/lib/apiwork/api/registry.rb +33 -0
  80. data/lib/apiwork/api/representation_registry.rb +76 -0
  81. data/lib/apiwork/api/resource/action.rb +41 -0
  82. data/lib/apiwork/api/resource.rb +648 -0
  83. data/lib/apiwork/api/router.rb +104 -0
  84. data/lib/apiwork/api/type_registry/definition.rb +117 -0
  85. data/lib/apiwork/api/type_registry.rb +99 -0
  86. data/lib/apiwork/api/union.rb +49 -0
  87. data/lib/apiwork/api.rb +85 -0
  88. data/lib/apiwork/configurable.rb +71 -0
  89. data/lib/apiwork/configuration/option.rb +125 -0
  90. data/lib/apiwork/configuration/validatable.rb +25 -0
  91. data/lib/apiwork/configuration.rb +95 -0
  92. data/lib/apiwork/configuration_error.rb +6 -0
  93. data/lib/apiwork/constraint_error.rb +20 -0
  94. data/lib/apiwork/contract/action/request.rb +79 -0
  95. data/lib/apiwork/contract/action/response.rb +87 -0
  96. data/lib/apiwork/contract/action.rb +258 -0
  97. data/lib/apiwork/contract/base.rb +714 -0
  98. data/lib/apiwork/contract/element.rb +130 -0
  99. data/lib/apiwork/contract/object/coercer.rb +194 -0
  100. data/lib/apiwork/contract/object/deserializer.rb +101 -0
  101. data/lib/apiwork/contract/object/transformer.rb +95 -0
  102. data/lib/apiwork/contract/object/validator/result.rb +27 -0
  103. data/lib/apiwork/contract/object/validator.rb +734 -0
  104. data/lib/apiwork/contract/object.rb +566 -0
  105. data/lib/apiwork/contract/request_parser/result.rb +25 -0
  106. data/lib/apiwork/contract/request_parser.rb +72 -0
  107. data/lib/apiwork/contract/response_parser/result.rb +25 -0
  108. data/lib/apiwork/contract/response_parser.rb +35 -0
  109. data/lib/apiwork/contract/union.rb +56 -0
  110. data/lib/apiwork/contract_error.rb +9 -0
  111. data/lib/apiwork/controller.rb +300 -0
  112. data/lib/apiwork/domain_error.rb +13 -0
  113. data/lib/apiwork/element.rb +386 -0
  114. data/lib/apiwork/engine.rb +20 -0
  115. data/lib/apiwork/error.rb +6 -0
  116. data/lib/apiwork/error_code/definition.rb +63 -0
  117. data/lib/apiwork/error_code/registry.rb +18 -0
  118. data/lib/apiwork/error_code.rb +132 -0
  119. data/lib/apiwork/export/base.rb +291 -0
  120. data/lib/apiwork/export/open_api.rb +600 -0
  121. data/lib/apiwork/export/pipeline/writer.rb +66 -0
  122. data/lib/apiwork/export/pipeline.rb +84 -0
  123. data/lib/apiwork/export/registry.rb +16 -0
  124. data/lib/apiwork/export/surface_resolver.rb +189 -0
  125. data/lib/apiwork/export/type_analysis.rb +170 -0
  126. data/lib/apiwork/export/type_script.rb +23 -0
  127. data/lib/apiwork/export/type_script_mapper.rb +349 -0
  128. data/lib/apiwork/export/zod.rb +39 -0
  129. data/lib/apiwork/export/zod_mapper.rb +421 -0
  130. data/lib/apiwork/export.rb +80 -0
  131. data/lib/apiwork/http_error.rb +16 -0
  132. data/lib/apiwork/introspection/action/request.rb +66 -0
  133. data/lib/apiwork/introspection/action/response.rb +57 -0
  134. data/lib/apiwork/introspection/action.rb +124 -0
  135. data/lib/apiwork/introspection/api/info/contact.rb +59 -0
  136. data/lib/apiwork/introspection/api/info/license.rb +49 -0
  137. data/lib/apiwork/introspection/api/info/server.rb +50 -0
  138. data/lib/apiwork/introspection/api/info.rb +107 -0
  139. data/lib/apiwork/introspection/api/resource.rb +83 -0
  140. data/lib/apiwork/introspection/api.rb +92 -0
  141. data/lib/apiwork/introspection/contract.rb +63 -0
  142. data/lib/apiwork/introspection/dump/action.rb +101 -0
  143. data/lib/apiwork/introspection/dump/api.rb +119 -0
  144. data/lib/apiwork/introspection/dump/contract.rb +129 -0
  145. data/lib/apiwork/introspection/dump/param.rb +486 -0
  146. data/lib/apiwork/introspection/dump/resource.rb +112 -0
  147. data/lib/apiwork/introspection/dump/type.rb +339 -0
  148. data/lib/apiwork/introspection/dump.rb +17 -0
  149. data/lib/apiwork/introspection/enum.rb +63 -0
  150. data/lib/apiwork/introspection/error_code.rb +44 -0
  151. data/lib/apiwork/introspection/param/array.rb +88 -0
  152. data/lib/apiwork/introspection/param/base.rb +285 -0
  153. data/lib/apiwork/introspection/param/binary.rb +73 -0
  154. data/lib/apiwork/introspection/param/boolean.rb +73 -0
  155. data/lib/apiwork/introspection/param/date.rb +73 -0
  156. data/lib/apiwork/introspection/param/date_time.rb +73 -0
  157. data/lib/apiwork/introspection/param/decimal.rb +121 -0
  158. data/lib/apiwork/introspection/param/integer.rb +131 -0
  159. data/lib/apiwork/introspection/param/literal.rb +45 -0
  160. data/lib/apiwork/introspection/param/number.rb +121 -0
  161. data/lib/apiwork/introspection/param/object.rb +59 -0
  162. data/lib/apiwork/introspection/param/reference.rb +45 -0
  163. data/lib/apiwork/introspection/param/string.rb +122 -0
  164. data/lib/apiwork/introspection/param/time.rb +73 -0
  165. data/lib/apiwork/introspection/param/union.rb +57 -0
  166. data/lib/apiwork/introspection/param/unknown.rb +26 -0
  167. data/lib/apiwork/introspection/param/uuid.rb +73 -0
  168. data/lib/apiwork/introspection/param.rb +31 -0
  169. data/lib/apiwork/introspection/type.rb +129 -0
  170. data/lib/apiwork/introspection.rb +28 -0
  171. data/lib/apiwork/issue.rb +80 -0
  172. data/lib/apiwork/json_pointer.rb +21 -0
  173. data/lib/apiwork/object.rb +1618 -0
  174. data/lib/apiwork/reference_generator.rb +638 -0
  175. data/lib/apiwork/registry.rb +56 -0
  176. data/lib/apiwork/representation/association.rb +391 -0
  177. data/lib/apiwork/representation/attribute.rb +335 -0
  178. data/lib/apiwork/representation/base.rb +819 -0
  179. data/lib/apiwork/representation/deserializer.rb +95 -0
  180. data/lib/apiwork/representation/element.rb +128 -0
  181. data/lib/apiwork/representation/inheritance.rb +78 -0
  182. data/lib/apiwork/representation/model_detector.rb +75 -0
  183. data/lib/apiwork/representation/root_key.rb +35 -0
  184. data/lib/apiwork/representation/serializer.rb +127 -0
  185. data/lib/apiwork/request.rb +79 -0
  186. data/lib/apiwork/response.rb +56 -0
  187. data/lib/apiwork/union.rb +102 -0
  188. data/lib/apiwork/version.rb +2 -2
  189. data/lib/apiwork.rb +61 -3
  190. data/lib/generators/apiwork/api_generator.rb +38 -0
  191. data/lib/generators/apiwork/contract_generator.rb +25 -0
  192. data/lib/generators/apiwork/install_generator.rb +27 -0
  193. data/lib/generators/apiwork/representation_generator.rb +25 -0
  194. data/lib/generators/apiwork/templates/api/api.rb.tt +4 -0
  195. data/lib/generators/apiwork/templates/contract/contract.rb.tt +6 -0
  196. data/lib/generators/apiwork/templates/install/application_contract.rb.tt +5 -0
  197. data/lib/generators/apiwork/templates/install/application_representation.rb.tt +5 -0
  198. data/lib/generators/apiwork/templates/representation/representation.rb.tt +6 -0
  199. data/lib/tasks/apiwork.rake +102 -0
  200. metadata +319 -19
  201. data/.rubocop.yml +0 -8
  202. data/sig/apiwork.rbs +0 -4
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ module Dump
6
+ class Action
7
+ def initialize(contract_action)
8
+ @contract_action = contract_action
9
+ end
10
+
11
+ def to_h
12
+ {
13
+ deprecated: @contract_action.deprecated?,
14
+ description: @contract_action.description || i18n_lookup(:description),
15
+ operation_id: @contract_action.operation_id,
16
+ raises: raises,
17
+ request: build_request(@contract_action.request),
18
+ response: build_response(@contract_action.response),
19
+ summary: @contract_action.summary || i18n_lookup(:summary),
20
+ tags: @contract_action.tags || [],
21
+ }
22
+ end
23
+
24
+ private
25
+
26
+ def i18n_lookup(field)
27
+ contract_class = @contract_action.contract_class
28
+ return nil unless contract_class.name
29
+
30
+ contract_class.api_class.translate(
31
+ :contracts,
32
+ contract_class.name.demodulize.delete_suffix('Contract').underscore,
33
+ :actions,
34
+ @contract_action.name,
35
+ field,
36
+ )
37
+ end
38
+
39
+ def build_request(request)
40
+ return { body: {}, query: {} } unless request
41
+
42
+ {
43
+ body: build_param(request.body),
44
+ query: build_param(request.query),
45
+ }
46
+ end
47
+
48
+ def build_param(param)
49
+ param ? Param.new(param).to_h : {}
50
+ end
51
+
52
+ def build_response(response)
53
+ return { body: {}, no_content: false } unless response
54
+ return { body: {}, no_content: true } if response.no_content?
55
+
56
+ body_shape = response.body
57
+ return { body: {}, no_content: false } unless body_shape
58
+
59
+ { body: Param.new(body_shape, result_wrapper: response.result_wrapper).to_h, no_content: false }
60
+ end
61
+
62
+ def raises
63
+ (api_level_raises + @contract_action.raises + auto_raises).uniq.sort_by(&:to_s)
64
+ end
65
+
66
+ def api_level_raises
67
+ api_class = @contract_action.contract_class.api_class
68
+ return [] unless api_class
69
+
70
+ api_class.raises
71
+ end
72
+
73
+ def auto_raises
74
+ return [] unless @contract_action.contract_class.representation?
75
+
76
+ action_name = @contract_action.name.to_sym
77
+ return [:unprocessable_entity] if [:create, :update].include?(action_name)
78
+
79
+ return [] if [:index, :show, :destroy].include?(action_name)
80
+
81
+ http_method = find_http_method
82
+ return [] unless http_method
83
+
84
+ [:post, :patch, :put].include?(http_method) ? [:unprocessable_entity] : []
85
+ end
86
+
87
+ def find_http_method
88
+ api_class = @contract_action.contract_class.api_class
89
+ return nil unless api_class
90
+
91
+ resource = api_class.root_resource.find_resource do |candidate|
92
+ candidate.contract_class == @contract_action.contract_class
93
+ end
94
+ return nil unless resource
95
+
96
+ resource.actions[@contract_action.name.to_sym]&.method
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ module Dump
6
+ class API
7
+ def initialize(api_class)
8
+ @api_class = api_class
9
+ @type_dump = Type.new(api_class)
10
+ end
11
+
12
+ def to_h
13
+ resources = build_resources
14
+ type_dump_hash = @type_dump.to_h
15
+
16
+ {
17
+ resources:,
18
+ base_path: @api_class.transform_path(@api_class.base_path),
19
+ enums: type_dump_hash[:enums],
20
+ error_codes: build_error_codes(collect_all_error_code_keys(resources)),
21
+ info: build_info,
22
+ types: type_dump_hash[:types],
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def collect_all_error_code_keys(resources)
29
+ error_code_keys = Set.new(@api_class.raises)
30
+
31
+ collect_action_error_codes(resources, error_code_keys)
32
+
33
+ error_code_keys.to_a.sort_by(&:to_s)
34
+ end
35
+
36
+ def collect_action_error_codes(resources, error_code_keys)
37
+ resources.each_value do |resource|
38
+ resource[:actions].each_value do |action|
39
+ error_code_keys.merge(action[:raises] || [])
40
+ end
41
+
42
+ collect_action_error_codes(resource[:resources], error_code_keys) if resource[:resources]
43
+ end
44
+ end
45
+
46
+ def build_error_codes(error_code_keys)
47
+ error_code_keys.each_with_object({}) do |code, hash|
48
+ error_code = Apiwork::ErrorCode.find!(code)
49
+ hash[code] = {
50
+ description: error_code.description(locale_key: @api_class.locale_key),
51
+ status: error_code.status,
52
+ }
53
+ end
54
+ end
55
+
56
+ def build_resources
57
+ @api_class.root_resource.resources.transform_values do |resource|
58
+ Resource.new(resource, @api_class).to_h
59
+ end
60
+ end
61
+
62
+ def build_info
63
+ info = @api_class.info
64
+
65
+ title = resolve_info_text(info, :title)
66
+ summary = resolve_info_text(info, :summary)
67
+ description = resolve_info_text(info, :description)
68
+
69
+ return nil unless info || title || summary || description
70
+
71
+ {
72
+ description:,
73
+ summary:,
74
+ title:,
75
+ contact: build_contact(info&.contact),
76
+ deprecated: info ? info.deprecated? : false,
77
+ license: build_license(info&.license),
78
+ servers: build_servers(info ? info.server : []),
79
+ tags: info ? info.tags : [],
80
+ terms_of_service: info&.terms_of_service,
81
+ version: info&.version,
82
+ }
83
+ end
84
+
85
+ def resolve_info_text(info, field)
86
+ info&.public_send(field) || @api_class.translate(:info, field)
87
+ end
88
+
89
+ def build_contact(contact)
90
+ return nil unless contact
91
+
92
+ {
93
+ email: contact.email,
94
+ name: contact.name,
95
+ url: contact.url,
96
+ }
97
+ end
98
+
99
+ def build_license(license)
100
+ return nil unless license
101
+
102
+ {
103
+ name: license.name,
104
+ url: license.url,
105
+ }
106
+ end
107
+
108
+ def build_servers(servers)
109
+ servers.map do |server|
110
+ {
111
+ description: server.description,
112
+ url: server.url,
113
+ }
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ module Dump
6
+ class Contract
7
+ def initialize(contract_class, expand: false)
8
+ @contract_class = contract_class
9
+ @expand = expand
10
+ @type_dump = Type.new(contract_class.api_class)
11
+ end
12
+
13
+ def to_h
14
+ @contract_class.api_class.ensure_all_contracts_built!
15
+
16
+ result = { actions: {} }
17
+
18
+ action_names = available_actions
19
+ action_names = @contract_class.actions.keys if action_names.empty?
20
+
21
+ action_names.each do |action_name|
22
+ contract_action = @contract_class.action_for(action_name)
23
+ result[:actions][action_name] = Action.new(contract_action).to_h if contract_action
24
+ end
25
+
26
+ if @expand
27
+ types, enums = build_referenced_types_and_enums(result[:actions])
28
+ else
29
+ types = build_local_types
30
+ enums = build_local_enums
31
+ end
32
+
33
+ result[:types] = types
34
+ result[:enums] = enums
35
+
36
+ result
37
+ end
38
+
39
+ private
40
+
41
+ def build_local_types
42
+ @contract_class.api_class.type_registry.each_pair
43
+ .select { |_name, type_definition| type_definition.scope == @contract_class }
44
+ .reject { |_, type_definition| type_definition.fragment? }
45
+ .sort_by { |name, _type_definition| name.to_s }
46
+ .each_with_object({}) do |(name, type_definition), result|
47
+ result[name] = @type_dump.build_type(name, type_definition)
48
+ end
49
+ end
50
+
51
+ def build_local_enums
52
+ @contract_class.api_class.enum_registry.each_pair
53
+ .select { |_name, enum_definition| enum_definition.scope == @contract_class }
54
+ .sort_by { |name, _enum_definition| name.to_s }
55
+ .each_with_object({}) do |(name, enum_definition), result|
56
+ result[name] = @type_dump.build_enum(name, enum_definition)
57
+ end
58
+ end
59
+
60
+ def build_referenced_types_and_enums(actions_dump)
61
+ type_registry = @contract_class.api_class.type_registry
62
+ enum_registry = @contract_class.api_class.enum_registry
63
+
64
+ referenced_types = Set.new
65
+ referenced_enums = Set.new
66
+ dumped_types = {}
67
+ visited_types = Set.new
68
+
69
+ collect_references(actions_dump, referenced_types, referenced_enums)
70
+
71
+ until (pending_types = referenced_types - visited_types).empty?
72
+ pending_types.each do |type_name|
73
+ visited_types << type_name
74
+
75
+ type_definition = type_registry[type_name]
76
+ next unless type_definition
77
+
78
+ dumped = @type_dump.build_type(type_name, type_definition)
79
+ dumped_types[type_name] = dumped
80
+
81
+ collect_references(dumped, referenced_types, referenced_enums)
82
+ end
83
+ end
84
+
85
+ dumped_enums = referenced_enums.each_with_object({}) do |enum_name, result|
86
+ enum_definition = enum_registry[enum_name]
87
+ result[enum_name] = @type_dump.build_enum(enum_name, enum_definition) if enum_definition
88
+ end
89
+
90
+ types = dumped_types.sort_by { |name, _| name.to_s }.to_h
91
+ enums = dumped_enums.sort_by { |name, _| name.to_s }.to_h
92
+
93
+ [types, enums]
94
+ end
95
+
96
+ def collect_references(dump, types, enums)
97
+ case dump
98
+ when Hash
99
+ types << dump[:reference].to_sym if dump[:type] == :reference && dump[:reference]
100
+
101
+ types << dump[:of][:reference].to_sym if dump[:of].is_a?(Hash) && dump[:of][:type] == :reference && dump[:of][:reference]
102
+
103
+ enums << dump[:enum] if dump[:enum].is_a?(Symbol)
104
+
105
+ dump.each_value { |value| collect_references(value, types, enums) }
106
+ when Array
107
+ dump.each { |item| collect_references(item, types, enums) }
108
+ end
109
+ end
110
+
111
+ def available_actions
112
+ return [] unless resource
113
+
114
+ resource.actions.keys
115
+ end
116
+
117
+ def resource
118
+ @contract_class.api_class.root_resource.find_resource(resource_name)
119
+ end
120
+
121
+ def resource_name
122
+ return nil unless @contract_class.name
123
+
124
+ @contract_class.name.demodulize.delete_suffix('Contract').underscore.pluralize.to_sym
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end